组合模式:将对象组合成树形结构以来表示"整体--部分"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
关于组合模式的定义有个关键词"树形",这个很关键,也很常见,如二叉树什么的。举个例子,如孝感城市,有教育部分和检察部门,孝感市下面的又有大悟县、红安县等县城,每个县城下面也有教育部分和检察部门,这个不就是一个树形结构吗(当然,还可以在县城叶子下面产生镇,镇也有教育部门和监察部门,这里仅仅是为了演示组合模式,叶子节点到县城这里就不在继续....)?
用C++来实现,我们可以定义一个City的基类,里面定义两个add和diaplay函数,其中add用来添加city的对象,display主要是为了打印结果来看看"树形";再定义个一个指定的城市类,继承自City,并实现add和display方法;最后定义个教育部门类EducationBureau和监察部门类SupervisionBureau,并实现display方法(add方法不实现,我们假设已经到最下面的叶子节点)。说起来可能不大明白,我们用UML类图来看看呗:
再来来点代码就应该更有助于理解了:
#include <iostream> #include <string> #include <vector> using namespace std; class City//城市的基类 { protected: string m_str; public: City(string str):m_str(str){} virtual ~City(){} virtual void add(City* city){} virtual void display(int dep){} }; class SpecifiedCity : public City //具体城市 { private: vector<City*> m_list_city; public: SpecifiedCity(string str):City(str){} ~SpecifiedCity(){} void add(City* city) { m_list_city.push_back(city); } void display(int dep) { for(int i=0; i<dep; i++) { cout<<"*"; } cout<<m_str<<endl; vector<City*>::iterator iter; for(iter = m_list_city.begin(); iter != m_list_city.end(); iter++) { (*iter)->display(dep+2);//此处+2完全是为了表示树形结构,并无其他含义 } } }; class EducationBureau : public City //教育部 { public: EducationBureau(string str):City(str){} virtual ~EducationBureau(){} void display(int dep) { for(int i=0; i<dep; i++) { cout<<"*"; } cout<<m_str<<endl; } }; class SupervisionBureau : public City//监察部 { public: SupervisionBureau(string str):City(str){} virtual ~SupervisionBureau(){} void display(int dep) { for(int i=0; i<dep; i++) { cout<<"*"; } cout<<m_str<<endl; } }; int main(int argc, char** argv) { City *pRoot =new SpecifiedCity("孝感市"); City* pLeafA = new EducationBureau("教育部门"); City* pLeafB = new SupervisionBureau("监察部门"); pRoot->add(pLeafA); pRoot->add(pLeafB); pRoot->display(1); City *pRootA = new SpecifiedCity("大悟县"); City* pLeafC = new EducationBureau("教育部门"); City* pLeafD = new SupervisionBureau("监察部门"); pRootA->add(pLeafC); pRootA->add(pLeafD); pRootA->display(4); City *pRootB = new SpecifiedCity("红安县"); City* pLeafE = new EducationBureau("教育部门"); City* pLeafF = new SupervisionBureau("监察部门"); pRootB->add(pLeafE); pRootB->add(pLeafF); pRootB->display(4); delete pRoot; delete pLeafA; pLeafB; delete pRootA; delete pLeafC; pLeafD; delete pRootB; delete pLeafE; pLeafF; return 0; }
要时还是不是很明白,那就看输出的"树形"结果吧:
以上代码在VS2013上编译通过。
以上的delete对象有点多哈,感觉有点笨。我开始想的使用智能指针来创建对象,但是最后添加时报错,调试了十来分钟没有弄好就没有弄,后面有时间再加上去,如果哪位大侠用智能指针实现了,麻烦发给我看看,我也想学习学习...........