组合模式
组合模式定义
组合模式(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
浙公网安备 33010602011771号