C++设计模式之组合模式
DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合使得用户对单个对象和组合对象的使用具有一致性。注意两个字“树形”。这种树形结构在现实生活中随处可见,比如一个集团公司,它有一个母公司,下设很多家子公司。不管是母公司还是子公司,都有各自直属的财务部、人力资源部、销售部等。对于母公司来说,不论是子公司,还是直属的财务部、人力资源部,都是它的部门。整个公司的部门拓扑图就是一个树形结构。
下面给出组合模式的UML图。从图中可以看到,FinanceDepartment、HRDepartment两个类作为叶结点,因此没有定义添加函数。而ConcreteCompany类可以作为中间结点,所以可以有添加函数。那么怎么添加呢?这个类中定义了一个链表,用来放添加的元素。
1 // Composite.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 #include<string> 7 #include <vector> 8 #include <list> 9 using namespace std; 10 11 class Company 12 { 13 public: 14 Company(string name) 15 { 16 m_name = name; 17 } 18 virtual ~Company() {} 19 virtual void Add(Company *pCom) {} 20 virtual void Show(int depth) {} 21 protected: 22 string m_name; 23 }; 24 25 class ConcreteCompany : public Company 26 { 27 public: 28 ConcreteCompany(string name):Company(name) {} 29 virtual ~ConcreteCompany() {} 30 void Add(Company *pCom) {m_listCompany.push_back(pCom);} 31 32 void Show(int depth) 33 { 34 for(int i = 0;i < depth; i++) 35 cout<<"-"; 36 cout<<m_name<<endl; 37 list<Company *>::iterator iter=m_listCompany.begin(); 38 for(; iter != m_listCompany.end(); iter++) //显示下层结点 39 (*iter)->Show(depth + 2); 40 } 41 private: 42 list<Company*> m_listCompany; 43 44 }; 45 46 //具体的部门,财务部 47 48 class FinanceDepartment : public Company 49 { 50 public: 51 FinanceDepartment(string name):Company(name){} 52 virtual ~FinanceDepartment() {} 53 virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点 54 { 55 for(int i = 0; i < depth; i++) 56 cout<<"-"; 57 cout<<m_name<<endl; 58 } 59 }; 60 61 class HRDepartment:public Company 62 { 63 public: 64 HRDepartment(string name):Company(name){} 65 virtual ~HRDepartment() {} 66 virtual void Show(int depth) 67 { 68 for(int i = 0; i < depth; i++) 69 cout<<"-"; 70 cout<<m_name<<endl; 71 } 72 }; 73 74 int _tmain(int argc, _TCHAR* argv[]) 75 { 76 Company *root = new ConcreteCompany("总公司"); 77 Company *leaf1=new FinanceDepartment("财务部"); 78 Company *leaf2=new HRDepartment("人力资源部"); 79 root->Add(leaf1); 80 root->Add(leaf2); 81 //分公司A 82 Company *mid1 = new ConcreteCompany("分公司A"); 83 Company *leaf3=new FinanceDepartment("财务部"); 84 Company *leaf4=new HRDepartment("人力资源部"); 85 mid1->Add(leaf3); 86 mid1->Add(leaf4); 87 root->Add(mid1); 88 89 //分公司B 90 Company *mid2=new ConcreteCompany("分公司B"); 91 FinanceDepartment *leaf5=new FinanceDepartment("财务部"); 92 HRDepartment *leaf6=new HRDepartment("人力资源部"); 93 mid2->Add(leaf5); 94 mid2->Add(leaf6); 95 root->Add(mid2); 96 root->Show(0); 97 98 delete leaf1; delete leaf2; 99 delete leaf3; delete leaf4; 100 delete leaf5; delete leaf6; 101 delete mid1; delete mid2; 102 delete root; 103 system("pause"); 104 return 0; 105 }