定义
(GoF《设计模式》):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组成
① Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
② Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
③ Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
适用性
以下情况下适用Composite模式:
1.你想表示对象的部分-整体层次结构
2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
例子
我们每天在公司上班,我们的公司其实就是一个树型结构的,最上边是总公司,总公司下面还有很多子公司, 而每个子公司有很很多部门。这样整个大公司就是一颗大树,每个子公司同时也是一颗小叔
首先是公司的抽象接口
[cpp] view plain copy print?
- // 公司抽象类
- class Company
- {
- public :
- Company(std::string name)
- :m_name(name)
- {
- }
- virtual ~Company( )
- {
- }
- virtual void Add(Company *pCompany) // 增加子公司
- {
- }
- virtual void Show(int depth) = 0; // 显示部门
- protected :
- std::string m_name; // 显示公司名字
- };
// 公司抽象类 class Company { public : Company(std::string name) :m_name(name) { } virtual ~Company( ) { } virtual void Add(Company *pCompany) // 增加子公司 { } virtual void Show(int depth) = 0; // 显示部门 protected : std::string m_name; // 显示公司名字 };
其次是公司的实现
[cpp] view plain copy print?
- // 公司类
- class ConcreteCompany : public Company
- {
- public :
- ConcreteCompany(std::string name)
- :Company(name)
- {
- }
- virtual ~ConcreteCompany( ){ }; // 虚析构函数
- void Add(Company *company) // 添加子公司
- {
- this->m_companyList.push_back(company); // 将子公司或者部门加入到公司的列表中
- }
- void Show(int depth) // 显示公司部门
- {
- for(int pos = 0; pos < depth; pos++)
- {
- std::cout <<"-";
- }
- std::cout <<this->m_name <<std::endl;
- for(std::list<Company *>::iterator it = this->m_companyList.begin( );
- it != this->m_companyList.end( );
- ++it)
- {
- (*it)->Show(depth + 2);
- }
- }
- protected :
- std::list<Company *> m_companyList; // 下属公司列表
- };
// 公司类 class ConcreteCompany : public Company { public : ConcreteCompany(std::string name) :Company(name) { } virtual ~ConcreteCompany( ){ }; // 虚析构函数 void Add(Company *company) // 添加子公司 { this->m_companyList.push_back(company); // 将子公司或者部门加入到公司的列表中 } void Show(int depth) // 显示公司部门 { for(int pos = 0; pos < depth; pos++) { std::cout <<"-"; } std::cout <<this->m_name <<std::endl; for(std::list<Company *>::iterator it = this->m_companyList.begin( ); it != this->m_companyList.end( ); ++it) { (*it)->Show(depth + 2); } } protected : std::list<Company *> m_companyList; // 下属公司列表 };
接着是财务部门的实现
[cpp] view plain copy print?
- // 财务部门
- class FinaceDepartment : public Company
- {
- public :
- FinaceDepartment(std::string name)
- :Company(name)
- {
- }
- virtual ~FinaceDepartment( )
- {
- }
- void Show(int depth) // 显示公司部门
- {
- for(int pos = 0; pos < depth; pos++)
- {
- std::cout <<"-";
- }
- std::cout <<this->m_name <<std::endl;
- }
- };
// 财务部门 class FinaceDepartment : public Company { public : FinaceDepartment(std::string name) :Company(name) { } virtual ~FinaceDepartment( ) { } void Show(int depth) // 显示公司部门 { for(int pos = 0; pos < depth; pos++) { std::cout <<"-"; } std::cout <<this->m_name <<std::endl; } };
然后是人力资源部门
[cpp] view plain copy print?
- // 人力部门
- class HRDepartment : public Company
- {
- public :
- HRDepartment(std::string name)
- :Company(name)
- {
- }
- virtual ~HRDepartment( ){ }; // 虚析构函数
- void Show(int depth) // 显示公司部门
- {
- for(int pos = 0; pos < depth; pos++)
- {
- std::cout <<"-";
- }
- std::cout <<this->m_name <<std::endl;
- }
- };
// 人力部门 class HRDepartment : public Company { public : HRDepartment(std::string name) :Company(name) { } virtual ~HRDepartment( ){ }; // 虚析构函数 void Show(int depth) // 显示公司部门 { for(int pos = 0; pos < depth; pos++) { std::cout <<"-"; } std::cout <<this->m_name <<std::endl; } };
最后是客户端代码
[cpp] view plain copy print?
- int main()
- {
- // 总公司
- Company *root = new ConcreteCompany("总公司");
- Company *rootHR = new HRDepartment("人力资源部");
- Company *rootFI = new FinaceDepartment("财务部");
- root->Add(rootHR);
- root->Add(rootFI);
- // 分公司A
- Company *left = new ConcreteCompany("分公司A");
- Company *leftHR = new HRDepartment("分公司A人力资源部");
- Company *leftFI = new FinaceDepartment("分公司A财务部");
- left->Add(leftHR);
- left->Add(leftFI);
- root->Add(left);
- // 分公司B
- Company *right = new ConcreteCompany("分公司B");
- Company *righHR = new HRDepartment("分公司B人力资源部");
- Company *righFI = new FinaceDepartment("分公司B财务部");
- right->Add(righHR);
- right->Add(righFI);
- root->Add(right);
- root->Show(0);
- return 0;
- }
int main() { // 总公司 Company *root = new ConcreteCompany("总公司"); Company *rootHR = new HRDepartment("人力资源部"); Company *rootFI = new FinaceDepartment("财务部"); root->Add(rootHR); root->Add(rootFI); // 分公司A Company *left = new ConcreteCompany("分公司A"); Company *leftHR = new HRDepartment("分公司A人力资源部"); Company *leftFI = new FinaceDepartment("分公司A财务部"); left->Add(leftHR); left->Add(leftFI); root->Add(left); // 分公司B Company *right = new ConcreteCompany("分公司B"); Company *righHR = new HRDepartment("分公司B人力资源部"); Company *righFI = new FinaceDepartment("分公司B财务部"); right->Add(righHR); right->Add(righFI); root->Add(right); root->Show(0); return 0; }
总结
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。
如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。本章使用了一个文件系统的例子来举例说明了组合模式的用途。在这个例子中,文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。
转载:http://blog.csdn.net/gatieme/article/details/21460519