组合模式

组合模式定义

组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式结构图

组合模式结构图如下所示:

图 01 组合模式结构图

组合模式套用代码

  1 #include "iostream"
  2 using namespace std; 
  3 #include <list>
  4 #include <string>
  5 
  6 
  7 class Component
  8 {
  9 protected:
 10     string name;
 11 public:
 12     Component(string name)
 13     {
 14         this->name = name;
 15     }
 16 
 17     virtual void Add(Component* c) = 0;
 18 
 19     virtual void Remove(Component* c) = 0;
 20 
 21     virtual void Display(int depth) = 0;
 22 
 23     virtual ~Component()
 24     {
 25     //    cout << "a" << endl;
 26     }
 27 };
 28 
 29 
 30 class Leaf : public Component
 31 {
 32 public:
 33     Leaf(string name) : Component(name)
 34     {
 35         
 36     }
 37 
 38     virtual void Add(Component* c)
 39     {
 40     
 41     }
 42 
 43     virtual void Remove(Component* c)
 44     {
 45     
 46     }
 47 
 48     virtual void Display(int depth)
 49     {
 50         string str(depth, '-');
 51         str += name;
 52         cout << str << endl;
 53     }
 54 
 55     virtual ~Leaf()
 56     {
 57     //    cout << "b" << endl;
 58     }
 59 };
 60 
 61 class Composite : public Component
 62 {
 63 private:
 64     list<Component*> component;
 65 public:
 66     Composite(string name) : Component(name)
 67     {
 68         
 69     }
 70 
 71     virtual void Add(Component* c)
 72     {
 73         component.push_back(c);
 74     }
 75 
 76     virtual void Remove(Component* c)
 77     {
 78         component.remove(c);
 79     }
 80 
 81     virtual void Display(int depth)
 82     {
 83         string str(depth,'-');
 84         str += name;
 85         cout << str << endl;
 86         
 87         list<Component*>::iterator it = component.begin();
 88         while(it != component.end())
 89         {
 90             // 这里有递归,也有多态
 91             (*it)->Display(depth+2);
 92             it++;
 93         }    
 94     }
 95 
 96     virtual ~Composite()
 97     {
 98     //    cout << "c" << endl;
 99     }
100 };
101 
102 int main()
103 {
104     cout<<"*******"<<endl;
105 
106     Component *root = new Composite("root"); 
107     Leaf* leaf1 = new Leaf("Leaf A");
108     root->Add(leaf1);
109 
110     Leaf* leaf2 = new Leaf("Leaf B");
111     root->Add(leaf2);
112 
113     Component *comp = new Composite("Composite X"); 
114     Leaf* leaf3 = new Leaf("Leaf XA");
115     comp->Add(leaf3);
116     Leaf* leaf4 = new Leaf("Leaf XB");
117     comp->Add(leaf4);
118     
119     root->Add(comp);
120 
121     Component *comp2 = new Composite("Composite XY"); 
122     Leaf* leaf5 = new Leaf("Leaf XYA");
123     comp2->Add(leaf5);
124     Leaf* leaf6 = new Leaf("Leaf XYB");
125     comp2->Add(leaf6);
126 
127     comp->Add(comp2);
128 
129     Leaf* leaf7 = new Leaf("Leaf c");
130     root->Add(leaf7);
131     
132     Leaf* leaf8 = new Leaf("Leaf D");
133     root->Add(leaf8);
134     root->Remove(leaf8);
135 
136     root->Display(1);
137 
138     cout<<"*******"<<endl;
139 
140     // 内存一定要释放
141     delete root;
142     delete comp;
143     delete comp2;
144     delete leaf1;
145     delete leaf2;
146     delete leaf3;
147     delete leaf4;
148     delete leaf5;
149     delete leaf6;
150     delete leaf7;
151     delete leaf8;
152 }

组合模式特点

① 透明方式,就是说在Component中声明所有用来管理子对象的方法,其中包括Add、Remove等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,他们具备完全一致的行为接口。但问题也很明显,因为Leaf类本身不具备Add、Remove方法的功能,所以实现它是没有意义的。

② 安全方式,就是说在Component接口中不去声明Add和Remove方法,那么子类的Leaf也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,这样做就不会出现透明方式提到的问题,不过由于不够透明,所以Leaf和Composite不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

③ 组合模式让客户可以一致地使用组合结构和单个对象。

组合模式实例应用

组合模式实例应用类图

图 02 组合模式实例应用类图

组合模式实例应用代码

  1 #include "iostream"
  2 #include <string>
  3 #include <list>
  4 using namespace std;
  5 
  6 class CCompany
  7 {
  8 protected:
  9     string name;
 10 public:
 11     CCompany(string name)
 12     {
 13         this->name = name;
 14     }
 15 
 16     virtual void Add(CCompany* c) = 0;
 17 
 18     virtual void Remove(CCompany* c) = 0;
 19 
 20     virtual void Display(int depth) = 0;
 21 
 22     virtual void LineOfDuty() = 0;
 23 
 24     virtual ~CCompany()
 25     {
 26     
 27     }
 28 };
 29 
 30 // 具体的公司,实现接口
 31 class CConcreteCompany : public CCompany
 32 {
 33 private:
 34     list<CCompany*> children;
 35 public:
 36     CConcreteCompany(string name)
 37     : CCompany(name)
 38     {
 39 
 40     }
 41 
 42     virtual void Add(CCompany* c)
 43     {
 44         children.push_back(c);
 45     }
 46 
 47     virtual void Remove(CCompany* c)
 48     {
 49         children.remove(c);
 50     }
 51 
 52     virtual void Display(int depth)
 53     {
 54         string str(depth,'-');
 55         str += name;
 56         cout << str << endl;
 57         
 58         list<CCompany*>::iterator it = children.begin();
 59         while(it != children.end())
 60         {
 61             (*it)->Display(depth+2);
 62             it++;
 63         }    
 64     }
 65 
 66     virtual void LineOfDuty()
 67     {
 68         list<CCompany*>::iterator it = children.begin();
 69         while(it != children.end())
 70         {
 71             (*it)->LineOfDuty();
 72             it++;
 73         }
 74     }
 75 
 76     virtual ~CConcreteCompany()
 77     {
 78     
 79     }
 80 };
 81 
 82 // 人力资源部
 83 class CHRDepartment : public CCompany
 84 {
 85 public:
 86     CHRDepartment(string name)
 87     : CCompany(name)
 88     {
 89 
 90     }
 91 
 92     virtual void Add(CCompany* c)
 93     {
 94         
 95     }
 96 
 97     virtual void Remove(CCompany* c)
 98     {
 99         
100     }
101 
102     virtual void Display(int depth)
103     {
104         string str(depth,'-');
105         str += name;
106         cout << str << endl;    
107     }
108 
109     virtual void LineOfDuty()
110     {
111         cout << "员工招聘培训管理" << name << endl;
112     }
113 
114     virtual ~CHRDepartment()
115     {
116     
117     }
118 };
119 
120 // 财务部
121 class CFinanceepartment : public CCompany
122 {
123 public:
124     CFinanceepartment(string name)
125     : CCompany(name)
126     {
127 
128     }
129 
130         virtual void Add(CCompany* c)
131     {
132         
133     }
134 
135     virtual void Remove(CCompany* c)
136     {
137         
138     }
139 
140     virtual void Display(int depth)
141     {
142         string str(depth,'-');
143         str += name;
144         cout << str << endl;    
145     }
146 
147     virtual void LineOfDuty()
148     {
149         cout << "公司财务收支管理" << name << endl;
150     }
151 
152     virtual ~CFinanceepartment()
153     {
154     
155     }
156 };
157 
158 void main()
159 {
160     cout<<"*******"<<endl;
161 
162     CCompany *root = new CConcreteCompany("北京总公司"); 
163     CHRDepartment* leaf1 = new CHRDepartment("总公司人力资源部");
164     root->Add(leaf1);
165     CFinanceepartment* leaf2 = new CFinanceepartment("总公司财务部");
166     root->Add(leaf2);
167 
168     CCompany *comp = new CConcreteCompany("上海华东分公司"); 
169     CHRDepartment* leaf3 = new CHRDepartment("华东分公司人力资源部");
170     comp->Add(leaf3);
171     CFinanceepartment* leaf4 = new CFinanceepartment("华东分公司财务部");
172     comp->Add(leaf4);
173     root->Add(comp);
174 
175     CCompany *comp1 = new CConcreteCompany("南京办事处"); 
176     CHRDepartment* leaf5 = new CHRDepartment("南京办事处人力资源部");
177     comp1->Add(leaf5);
178     CFinanceepartment* leaf6 = new CFinanceepartment("南京办事处财务部");
179     comp1->Add(leaf6);
180     comp->Add(comp1);
181     
182     CCompany *comp2 = new CConcreteCompany("杭州办事处"); 
183     CHRDepartment* leaf7 = new CHRDepartment("杭州办事处人力资源部");
184     comp2->Add(leaf7);
185     CFinanceepartment* leaf8 = new CFinanceepartment("杭州办事处财务部");
186     comp2->Add(leaf8);
187     comp->Add(comp2);
188 
189     cout << "结构图" << endl;
190     root->Display(1);
191     cout << "职责" << endl;
192     root->LineOfDuty();
193     cout<<"*******"<<endl;
194 
195     // 内存一定要释放
196     delete root;
197     delete comp;
198     delete comp1;
199     delete comp2;
200     delete leaf1;
201     delete leaf2;
202     delete leaf3;
203     delete leaf4;
204     delete leaf5;
205     delete leaf6;
206     delete leaf7;
207     delete leaf8;
208 }

2014-12-04   22:21:45

 

posted on 2014-12-04 21:57  xiaoheike  阅读(236)  评论(0)    收藏  举报

导航