組合模式
意圖:
將對象組合成樹形結構以表示‘部分-整體’的層次結構,所以有時候又叫做部分-整體模式。組合模式使得用戶對單個對象和組合對象的使用具有一致性。,它使我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以向處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。
適用性:
當你發現需求中是體現部分與整體層次的結構時,以及你希望用戶可以忽略組合對象與單個對象的不同,統一的使用組合結構中的所有對象時。
優點:
組合模式使得基本對象可以被組合成更復雜的組合對象,而這個組合對象又可以被組合,這樣不斷的遞歸下去,客戶代碼中,任何用到基本對象的地方都可以使用組合對象了。
組合模式讓客戶可以一致的使用組合結構和單個對象。
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 }