组合模式:将对象组合成树形结构来表示“部分-整体”的关系,组合模式使得单个对象和组合对象使用具有一致性。UML类图如下:
实现一个公司的办公管理系统,父公司下面可能既有子部门也有子公司。UML类图如下:
c++代码实现如下:
#include<exception>
#include <iostream>
#include<string>
#include<list>
using namespace std;
//10.组合模式:办公管理系统
class Component
{
public:
Component(const string &istrName) :m_strName(istrName){};
virtual ~Component(){}
string getName(){ return m_strName; }
virtual void addComponent(Component* ipCom) = 0;
virtual Component* removeComponent(const string &istrName) = 0;
virtual void display(int depth) = 0;
protected:
string m_strName;
};
class ConcreteComponent :public Component
{
public:
ConcreteComponent(const string &istrName) :Component(istrName){}
void addComponent(Component* ipCom) override
{
m_coms.push_back(ipCom);
}
Component* removeComponent(const string &istrName)override
{
Component *pCom = NULL;
for (auto itr = m_coms.begin(); itr != m_coms.end();++itr)
{
if ((*itr)->getName()==istrName)
{
pCom = *itr;
m_coms.erase(itr);
break;
}
}
return pCom;
}
void display(int depth) override
{
string line(depth,'-');
line += m_strName;
cout << line << endl;
for (auto itr = m_coms.begin(); itr != m_coms.end(); ++itr)
{
(*itr)->display(depth + 2);
}
}
private:
list<Component *>m_coms;
};
class LeafComponent :public Component
{
public:
LeafComponent(const string &istrName) :Component(istrName){};
void addComponent(Component* ipCom)
{
cout << "部门不能增加子公司!" << endl;
}
Component *removeComponent(const string &istrName)
{
cout << "部门下没有子公司!" << endl;
return NULL;
}
void display(int depth)
{
string line(depth,'-');
line += m_strName;
cout << line << endl;
}
};
int main()
{
ConcreteComponent root("北京总公司");
LeafComponent leaf1("hr部");
LeafComponent leaf2("技术部");
LeafComponent leaf3("财务部");
root.addComponent(&leaf1);
root.addComponent(&leaf2);
root.addComponent(&leaf3);
ConcreteComponent childCom("武汉办事处");
LeafComponent leaf4("武汉办事处hr部");
LeafComponent leaf5("武汉办事处技术部");
childCom.addComponent(&leaf4);
childCom.addComponent(&leaf5);
root.addComponent(&childCom);
root.display(1);
system("pause");
}