组合模式:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
当发现需求中是体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。
组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司、办事处等组合对象的类层次。基本对象可以被组合成更复杂的组合对象,而组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。组合模式让客户可以一致的使用组合结构和单个对象。原则上只要业务涉及到分层就可以用组合模式,但是如果每个层次和每个业务都有相同点的时候更有利于用组合模式,而且相同点和不同点的有对应的接口更好,这样就把相同的接口泛化到最上层,然后通过自己调用自己,来让子类继承的时候调用父类对象(子类转化为父类对象),这样就形成了递归,也就是所谓的层次结构。1 targetver.h 2 #include<iostream> 3 #include<vector> 4 #include<string> 5 using namespace std; 6 class Company 7 { 8 public: 9 Company(); 10 Company(string); 11 virtual void add(Company* c); 12 virtual void remove(Company* c); 13 virtual void display(int depth); 14 virtual void duty(); 15 protected: 16 string name; 17 }; 18 class Finance:public Company 19 { 20 public: 21 Finance(string); 22 void add(Company* c); 23 void remove(Company* c); 24 void display(int depth); 25 void duty(); 26 }; 27 class HumanResource:public Company 28 { 29 public: 30 HumanResource(string); 31 void add(Company* c); 32 void remove(Company* c); 33 void display(int depth); 34 void duty(); 35 }; 36 class ConcreteCompany:public Company 37 { 38 public: 39 ConcreteCompany(string); 40 void add(Company* c); 41 void remove(Company* c); 42 void display(int depth); 43 void duty(); 44 private: 45 vector<Company*> company; 46 }; 47 48 49 stdafx.cpp 50 #include "stdafx.h" 51 /** 52 **Company类的接口,不需要实现 53 **/ 54 Company::Company(string na){name=na;} 55 Company::Company(){} 56 void Company::add(Company* c){} 57 void Company::remove(Company* c){} 58 void Company::display(int depth){} 59 void Company::duty(){} 60 /** 61 **Finance类的接口,具体类 62 **/ 63 Finance::Finance(string na):Company(na){} 64 void Finance::add(Company* c){/*叶子类,为空*/ } 65 void Finance::remove(Company* c){/*叶子类,为空*/ } 66 void Finance::display(int depth){string s(depth,'-');cout<<s<<name<<endl;} 67 void Finance::duty(){cout<<name<<" 公司财务收支管理" <<endl;} 68 /** 69 **HumanResource类的接口,具体类 70 **/ 71 HumanResource::HumanResource(string na):Company(na){} 72 void HumanResource::add(Company* c){/*叶子类,为空*/ } 73 void HumanResource::remove(Company* c){/*叶子类,为空*/} 74 void HumanResource::display(int depth){string s(depth,'-');cout<<s<<name<<endl;} 75 void HumanResource::duty(){cout<<name<<" 员工招聘培训管理" <<endl;} 76 /** 77 **ConcreteCompany类的接口,具体类 78 **/ 79 ConcreteCompany::ConcreteCompany(string na):Company(na){} 80 void ConcreteCompany::add(Company* c){company.push_back(c);} 81 void ConcreteCompany::remove(Company* c){cout<<"暂未实现"<<endl;} 82 void ConcreteCompany::display(int depth) 83 { 84 string s(depth, '-'); 85 cout<<s<<name<<endl; 86 for (vector<Company*>::iterator iter=company.begin();iter!=company.end();iter++) 87 { 88 (*iter)->display(depth+5); 89 } 90 } 91 void ConcreteCompany::duty() 92 { 93 for (vector<Company*>::iterator iter=company.begin();iter!=company.end();iter++) 94 { 95 (*iter)->duty(); 96 } 97 } 98 99 Composite.cpp 100 #include "stdafx.h" 101 int _tmain (int argc, _TCHAR* argv[]) 102 { 103 ConcreteCompany *root= new ConcreteCompany("北京总公司" ); 104 root->add( new HumanResource("总公司人力资源部" )); 105 root->add( new Finance("总公司财务部 " )); 106 107 ConcreteCompany *comp= new ConcreteCompany("上海华东分公司" ); 108 comp->add( new HumanResource("华东分公司人力资源部" )); 109 comp->add( new Finance("华东分公司财务部" )); 110 root->add(comp); 111 112 ConcreteCompany *compn= new ConcreteCompany("南京办事处" ); 113 compn->add( new HumanResource("南京办事处人力资源部" )); 114 compn->add( new Finance("南京办事处财务部" )); 115 comp->add(compn); 116 117 ConcreteCompany *compn1= new ConcreteCompany("杭州办事处" ); 118 compn1->add( new HumanResource("杭州办事处人力资源部" )); 119 compn1->add( new Finance("杭州办事处财务部" )); 120 comp->add(compn1); 121 122 cout<< "结构图" <<endl; 123 root->display(1); 124 root->duty(); 125 return 0; 126 }