参考《大话设计模式》的代理模式,把C#改写成c++的实现 。
参考 设计模式C++实现(7)——外观模式、组合模式这篇博客
DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合使得用户对单个对象和组合对象的使用具有一致性。
例如:一个公司有下面有各个部门,还有分公司。分公司和总公司一样,也有不同的部门,下面可以还有分公司。
这里使用了智能指针来实现多态,可以参考这里。
1.公司类(基类)
因为C++里面,抽象类不能实例化,所以这里公司类就没有定义成抽象类了
class Company
{
public:
Company(string name) { m_name = name; }
virtual ~Company(){cout<<"删除 "<<m_name<<endl;}
virtual void Add(shared_ptr<Company> pCom){}
virtual void remove(shared_ptr<Company> pCom){}
virtual void Show(int depth)
{
for(int i = 0; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
protected:
string m_name;
};
2.具体公司类(实现接口或者方法)
//具体公司
class ConcreteCompany : public Company
{
public:
ConcreteCompany(string name): Company(name) {}
virtual ~ConcreteCompany() {}
void Add(shared_ptr<Company> pCom) { m_listCompany.push_back(pCom); } //位于树的中间,可以增加子树
void remove(shared_ptr<Company> pCom){m_listCompany.remove(pCom);}
void Show(int depth)
{
for(int i = 0;i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
// list<shared_ptr<Company>>::iterator iter=m_listCompany.begin();
// for(; iter != m_listCompany.end(); iter++) //显示下层结点
// (*iter)->Show(depth + 2);
for(const auto& company:m_listCompany)
company->Show(depth+2);
}
private:
list<shared_ptr<Company>> m_listCompany;
};
3.两个具体部门
//具体的部门,财务部
class FinanceDepartment : public Company
{
public:
FinanceDepartment(string name):Company(name){}
virtual ~FinanceDepartment() {}
virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
{
for(int i = 0; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
};
//具体的部门,人力资源部
class HRDepartment :public Company
{
public:
HRDepartment(string name):Company(name){}
virtual ~HRDepartment() {}
virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
{
for(int i = 0; i < depth; i++)
cout<<"-";
cout<<m_name<<endl;
}
};
这两个类其实可以添加Add和remove两个函数,与基类保存一直。但是我觉得这两个部门没有这两个功能,可以不写上。
4.客服端
int main()
{
shared_ptr<Company> root = make_shared<ConcreteCompany>("总公司");
shared_ptr<Company> leaf1=make_shared<FinanceDepartment>("总公司人力资源部");
shared_ptr<Company> leaf2=make_shared<HRDepartment>("总公司财务部");
root->Add(leaf1);
root->Add(leaf2);
//分公司A
shared_ptr<Company> midA = make_shared<ConcreteCompany>("分公司A");
shared_ptr<Company> leaf3=make_shared< FinanceDepartment>("分公司A人力资源部");
shared_ptr<Company> leaf4=make_shared< HRDepartment>("分公司A财务部");
midA->Add(leaf3);
midA->Add(leaf4);
root->Add(midA);
//分公司B
shared_ptr<Company> midB=make_shared< ConcreteCompany>("分公司B");
shared_ptr<Company> leaf5=make_shared< FinanceDepartment>("分公司B人力资源部");
shared_ptr<Company> leaf6=make_shared< HRDepartment>("分公司B财务部");
midB->Add(leaf5);
midB->Add(leaf6);
root->Add(midB);
//分公司B_1
shared_ptr<Company> midB_1=make_shared< ConcreteCompany>("分公司B_1");
shared_ptr<Company> leaf7=make_shared< FinanceDepartment>("分公司B_1人力资源部");
shared_ptr<Company> leaf8=make_shared< HRDepartment>("分公司B_1财务部");
midB_1->Add(leaf7);
midB_1->Add(leaf8);
midB->Add(midB_1);
//分公司A_1
shared_ptr<Company> midA_1=make_shared< ConcreteCompany>("分公司A_1");
shared_ptr<Company> leaf9=make_shared< FinanceDepartment>("分公司A_1人力资源部");
shared_ptr<Company> leaf10=make_shared< HRDepartment>("分公司A_1财务部");
midA_1->Add(leaf9);
midA_1->Add(leaf10);
midA->Add(midA_1);
shared_ptr<Company> leaf11=make_shared< HRDepartment>("分公司A_2财务部");
midA->Add(leaf11);
midA->remove(leaf11);
root->Show(0);
return 0;
}
需要添加三个头文件
#include <iostream>
#include <list>
#include <memory>
using namespace std;
运行结果图:
5.总结
这里使用了智能指针来代替内置指针,可以避免手动删除指针。程序结束之后,调用析构函数,自动释放内存。