组合模式:将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
Conponent:为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。
通常都用add和remove方法来增加或移除树叶或树枝的功能。
Leaf:在组合中表示叶节点对象,叶节点没有子节点
Composite:定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作。比如增加add和删除remove。同时需要对下级进行遍历。
透明方式:叶节点也实现
在Component中声明所有用来管理子对象的方法,其中包括add,remove等。这样实现Component接口的所有子类都具备add和remove,对外界同意。
安全方式:
在Component接口中不去声明add和remove方法,那么子类的Leaf也不需要实现他。在Composite中声明所有用来管理子类对象的方法。
缺点:客户端调用需要判断,不方便。
何时使用:
需求中是体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑使用组合模式。
优点:
基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合。这样不断递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象。
组合模式可以让客户一致地使用组合结构和单个对象。
main.cpp
#include <iostream> #include <stdlib.h> #include <memory> #include "Company.h" #include "ConcreteCompany.h" #include "FinanceDepartment.h" #include "HRDepartment.h" using namespace std; void process() { shared_ptr<Company> ptrConcreteCompany(new ConcreteCompany("总公司")); shared_ptr<Company> ptrFinanceDepartment(new FinanceDepartment("财务部")); shared_ptr<Company> ptrHRDepartment(new HRDepartment("人力资源部")); ptrConcreteCompany->add(ptrFinanceDepartment); ptrConcreteCompany->add(ptrHRDepartment); //分公司A shared_ptr<Company> ptrMidCompany(new ConcreteCompany("分公司A")); shared_ptr<Company> ptrMidFinanceDepartment(new ConcreteCompany("分公司A的财务部")); shared_ptr<Company> ptrMidHRDepartment(new HRDepartment("分公司A的人力资源部")); ptrMidCompany->add(ptrMidFinanceDepartment); ptrMidCompany->add(ptrMidHRDepartment); ptrConcreteCompany->add(ptrMidCompany); //分公司B shared_ptr<Company> ptrMid2Company(new ConcreteCompany("分公司B")); shared_ptr<Company> ptrMid2FinanceDepartment(new ConcreteCompany("分公司B的财务部")); shared_ptr<Company> ptrMid2HRDepartment(new HRDepartment("分公司B的人力资源部")); ptrMid2Company->add(ptrMid2FinanceDepartment); ptrMid2Company->add(ptrMid2HRDepartment); ptrConcreteCompany->add(ptrMid2Company); ptrConcreteCompany->show(0); } int main(int argc,char* argv[]) { process(); system("pause"); return 0; }
Company.h
#ifndef COMPANY_H #define COMPANY_H #include <string> #include <memory> #include <vector> class Company { public: Company(const std::string& sName); virtual ~Company(void); virtual void add(std::shared_ptr<Company> ptrCompmany); virtual void show(int iDepth); protected: std::string _sName; }; #endif
Company.cpp
#include "Company.h" #include <iostream> using namespace std; Company::Company(const std::string& sName):_sName(sName) { } Company::~Company(void) { } //位于树的中间,可以增加子树 void Company::add(std::shared_ptr<Company> ptrCompany) { } //显示下层结点 void Company::show(int iDepth) { }
ConcreteCompany.h
#ifndef CONCRETECOMPANY_H #define CONCRETECOMPANY_H #include "company.h" #include <string> class ConcreteCompany : public Company { public: ConcreteCompany(const std::string& sName); ~ConcreteCompany(void); virtual void add(std::shared_ptr<Company> ptrCompany); virtual void show(int iDepth); private: std::vector< std::shared_ptr<Company> > _vecPtrCompany; }; #endif
ConcreteCompany.cpp
#include "ConcreteCompany.h" #include <iostream> using namespace std; ConcreteCompany::ConcreteCompany(const std::string& sName):Company(sName) { } ConcreteCompany::~ConcreteCompany(void) { } void ConcreteCompany::add(std::shared_ptr<Company> ptrCompany) { _vecPtrCompany.push_back(ptrCompany); } void ConcreteCompany::show(int iDepth) { for(int i = 0 ; i < iDepth ; i++) { cout << "-"; } cout << _sName << endl; //显示下层结点 vector< std::shared_ptr<Company> >::iterator it = _vecPtrCompany.begin(); for(; it != _vecPtrCompany.end() ; it++) { (*it)->show(iDepth + 2); } }
FinanceDepartment.h
#ifndef FINANCEDEPARTMENT_H #define FINANCEDEPARTMENT_H #include "company.h" //具体的部门,财务部 class FinanceDepartment : public Company { public: FinanceDepartment(const std::string& sName); virtual ~FinanceDepartment(void); //只需显示,无限添加函数,因为是叶节点 virtual void show(int iDepth); }; #endif
FinanceDepartment.cpp
#include "FinanceDepartment.h" #include <iostream> using namespace std; FinanceDepartment::FinanceDepartment(const std::string& sName):Company(sName) { } FinanceDepartment::~FinanceDepartment(void) { } void FinanceDepartment::show(int iDepth) { for(int i = 0 ; i < iDepth ; i++) { cout << "-"; } cout << _sName << endl; }
HRDepartment.h
#pragma once #include "company.h" #include <string> //具体的部门,人力资源部 class HRDepartment : public Company { public: HRDepartment(const std::string& sName); virtual ~HRDepartment(void); virtual void show(int iDepth); };
HRDepartment.cpp
#include "HRDepartment.h" #include <iostream> using namespace std; HRDepartment::HRDepartment(const std::string& sName):Company(sName) { } HRDepartment::~HRDepartment(void) { } //只需显示,无限添加函数,因为已经是叶节点 void HRDepartment::show(int iDepth) { for(int i = 0 ; i < iDepth ; i++) { cout << "-" ; } cout << _sName << endl; }