组合模式
意图:
将对象组合成树形结构以表示‘部分-整体’的层次结构,所以有时候又叫做部分-整体模式。组合模式使得用户对单个对象和组合对象的使用具有一致性。,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
适用性:
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时。
优点:
组合模式使得基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
组合模式让客户可以一致的使用组合结构和单个对象。
UML:
抽象构件(Component)角色:这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。在安全式的合成模式里,构件角色并不是定义出管理子对象的方法,这一定义由树枝构件对象给出。
树叶构件(Leaf)角色:树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
树枝构件(Composite)角色:代表参加组合的有下级子对象的对象。树枝对象给出所有的管理子对象的方法,如add()、remove()、getChild()等。
代码实现:输出对应公司结构和其部门职责,这里总公司、分公司、各种部门都有共同的接口
composite.h实现:
1 #ifndef COMPOSITE_H 2 #define COMPOSITE_H 3 4 #include <list> 5 using std::list; 6 7 #include <string> 8 using std::string; 9 10 #include <iostream> 11 using namespace std; 12 13 class Company 14 { 15 public: 16 Company(char* name):mName(name){} 17 virtual void attach(Company* cpn){} 18 virtual void detach(Company* cpn){} 19 virtual void display(string str){} 20 21 virtual void LineOfDuty(string company){} 22 23 protected: 24 char* mName; 25 list<Company* > mList; 26 }; 27 28 class ConcreteCompany:public Company{ 29 public: 30 ConcreteCompany(char* name):Company(name){} 31 virtual void attach(Company* cpn); 32 virtual void detach(Company* cpn); 33 virtual void display(string str); 34 virtual void LineOfDuty(string company); 35 }; 36 37 class HrDepartment:public Company{ 38 public: 39 HrDepartment(char* name):Company(name){} 40 virtual void display(string str); 41 42 virtual void LineOfDuty(string company); 43 }; 44 45 class FinanceDepartment:public Company{ 46 public: 47 FinanceDepartment(char* name):Company(name){} 48 virtual void display(string str); 49 50 virtual void LineOfDuty(string company); 51 }; 52 53 54 #endif
composite.cpp:
1 #include "composite.h" 2 #include <iostream> 3 using namespace std; 4 5 void ConcreteCompany::attach(Company* cpn) 6 { 7 if(nullptr != cpn) 8 { 9 mList.push_back(cpn); 10 } 11 } 12 13 void ConcreteCompany::detach(Company* cpn) 14 { 15 if(nullptr != cpn) 16 { 17 mList.remove(cpn); 18 } 19 } 20 21 void ConcreteCompany::display(string str) 22 { 23 list<Company* >::iterator beg = mList.begin(); 24 cout<<str<<mName<<endl; 25 str = str + str; 26 for ( ; beg != mList.end(); beg++) 27 { 28 (*beg)->display(str); 29 } 30 } 31 32 void ConcreteCompany::LineOfDuty(string company) 33 { 34 list<Company* >::iterator beg = mList.begin(); 35 string name = mName; 36 for ( ; beg != mList.end(); beg++) 37 { 38 (*beg)->LineOfDuty(name); 39 } 40 } 41 42 void HrDepartment::display(string str) 43 { 44 cout<<str<<mName<<endl; 45 } 46 47 void HrDepartment::LineOfDuty(string company) 48 { 49 cout<<company<<"员工招聘培训管理!"<<endl; 50 } 51 52 void FinanceDepartment::display(string str) 53 { 54 cout<<str<<mName<<endl; 55 } 56 57 void FinanceDepartment::LineOfDuty(string company) 58 { 59 cout<<company<<"公司财务收支管理!"<<endl; 60 }
main.cpp:
1 #include <iostream> 2 #include "composite.h" 3 using namespace std; 4 5 void main() 6 { 7 // 8 ConcreteCompany com1("木鸟飞公司"); 9 FinanceDepartment com2("总公司财务部"); 10 HrDepartment com3("总公司人力部"); 11 12 com1.attach(&com2); 13 com1.attach(&com3); 14 15 ConcreteCompany com11("木鸟飞东北分公司"); 16 FinanceDepartment com22("东北分公司财务部"); 17 HrDepartment com33("东北分公司人力部"); 18 19 com11.attach(&com22); 20 com11.attach(&com33); 21 22 com1.attach(&com11); 23 24 string str("─"); 25 com1.display(str); 26 27 cout<<endl; 28 29 com1.LineOfDuty(str); 30 return; 31 }