015 --- 第19章 组合模式
简述:
组合模式:将对象组合成树形结构以表示‘部分 - 整体‘的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式包括:树类、枝类、叶类。
树类:组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理枝的子部件。
枝类:定义有枝节点的行为,用来存储子部件,在树类接口中实现与子部件有关的操作。
叶类:在组合中表示叶节点对象,叶节点没有子节点。
应用场景:叶类和枝类共同继承自树类,叶类没有子节点,只处理自己的逻辑;枝类中存在一个子枝类和子叶类的数据结构,进行逻辑处理
注:开发环境调整为VS2017,操作系统win11
组合模式:
1 #include <iostream> 2 #include <string> 3 #include <list> 4 using namespace std; 5 6 // 树类 7 class CComponent 8 { 9 protected: 10 string m_szName; 11 12 public: 13 CComponent(string szName) { m_szName = szName; } 14 15 virtual void Add(CComponent* pComponent) = 0; 16 virtual void Remove(CComponent* pComponent) = 0; 17 virtual void Display(int nDepth) = 0; 18 }; 19 20 // 叶类 21 class CLeaf : public CComponent 22 { 23 public: 24 CLeaf(string szName) : CComponent(szName) {} 25 26 void Add(CComponent* pComponent) 27 { 28 cout << "叶子结点不能增加子节点" << endl; 29 } 30 31 void Remove(CComponent* pComponent) 32 { 33 cout << "叶子结点不能删除子节点" << endl; 34 } 35 36 void Display(int nDepth) 37 { 38 string str(nDepth, '-'); 39 40 cout << str << m_szName << endl; 41 } 42 }; 43 44 // 枝类 45 class CComposite : public CComponent 46 { 47 private: 48 list<CComponent*> m_lstChildren; 49 50 public: 51 CComposite(string szName) : CComponent(szName) {}; 52 53 void Add(CComponent* pComponent) { m_lstChildren.push_back(pComponent); } 54 55 void Remove(CComponent* pComponent) { m_lstChildren.remove(pComponent); } 56 57 void Display(int nDepth) 58 { 59 string str(nDepth, '-'); 60 61 cout << str << m_szName << endl; 62 63 for (CComponent* pComponent : m_lstChildren) 64 pComponent->Display(nDepth + 2); 65 } 66 }; 67 68 int main() 69 { 70 CComposite root("root"); 71 CLeaf LeafA("Leaf A"); 72 root.Add(&LeafA); 73 CLeaf LeafB("Leaf B"); 74 root.Add(&LeafB); 75 76 CComposite compX("Composite X"); 77 CLeaf LeafXA("Leaf XA"); 78 compX.Add(&LeafXA); 79 CLeaf LeafXB("Leaf XB"); 80 compX.Add(&LeafXB); 81 root.Add(&compX); 82 83 CComposite compY("Composite Y"); 84 CLeaf LeafYA("Leaf YA"); 85 compY.Add(&LeafYA); 86 CLeaf LeafYB("Leaf YB"); 87 compY.Add(&LeafYB); 88 root.Add(&compY); 89 90 CLeaf LeafC("Leaf C"); 91 root.Add(&LeafC); 92 93 CLeaf LeafD("Leaf D"); 94 root.Add(&LeafD); 95 root.Remove(&LeafD); 96 97 CLeaf LeafE("Leaf E"); 98 LeafD.Add(&LeafE); 99 100 root.Display(1); 101 102 system("pause"); 103 return 0; 104 }
输出结果:
例:公司组织结构
代码如下:
#include <iostream> #include <string> #include <list> using namespace std; // 抽象公司类(树类) class CCompany { protected: string m_szName; public: CCompany(string szName) { m_szName = szName; } virtual void Add(CCompany* pCompany) = 0; virtual void Remove(CCompany* pCompan) = 0; virtual void Display(int nDepth) = 0; virtual void LineOfDuty() = 0; }; // 具体公司类(枝类) class CConcreteCompany : public CCompany { private: list<CCompany*> m_lstChildren; public: CConcreteCompany(string szName) : CCompany(szName) {} virtual void Add(CCompany* pCompany) { m_lstChildren.push_back(pCompany); } virtual void Remove(CCompany* pCompany) { m_lstChildren.remove(pCompany); } virtual void Display(int nDepth) { string str(nDepth, '-'); cout << str << m_szName << endl; for (CCompany* pCompany : m_lstChildren) pCompany->Display(nDepth + 2); } virtual void LineOfDuty() { for (CCompany* pCompany : m_lstChildren) pCompany->LineOfDuty(); } }; // 人力资源部(叶类) class CHRDepartment : public CCompany { public: CHRDepartment(string szName) : CCompany(szName) {} virtual void Add(CCompany* pCompany) {} virtual void Remove(CCompany* pCompany) {} virtual void Display(int nDepth) { string str(nDepth, '-'); cout << str << m_szName << endl; } virtual void LineOfDuty() { cout << m_szName << ":员工招聘培训管理" << endl; } }; // 财务部 class CFinanceDepartment : public CCompany { public: CFinanceDepartment(string szName) : CCompany(szName) {} virtual void Add(CCompany* pCompany) {} virtual void Remove(CCompany* pCompany) {} virtual void Display(int nDepth) { string str(nDepth, '-'); cout << str << m_szName << endl; } virtual void LineOfDuty() { cout << m_szName << ":公司财务收支管理" << endl; } }; int main() { CConcreteCompany root("北京总公司"); CHRDepartment HRDepartment1("总公司人力资源部"); root.Add(&HRDepartment1); CFinanceDepartment FinanceDepartment1("总公司财务部"); root.Add(&FinanceDepartment1); CConcreteCompany comp("上海华东分公司"); CHRDepartment HRDepartment2("华东分公司人力资源部"); comp.Add(&HRDepartment2); CFinanceDepartment FinanceDepartment2("华东分公司财务部"); comp.Add(&FinanceDepartment2); root.Add(&comp); CConcreteCompany comp1("南京办事处"); CHRDepartment HRDepartment3("南京办事处人力资源部"); comp1.Add(&HRDepartment3); CFinanceDepartment FinanceDepartment3("南京办事处财务部"); comp1.Add(&FinanceDepartment3); root.Add(&comp1); CConcreteCompany comp2("杭州办事处"); CHRDepartment HRDepartment4("杭州办事处人力资源部"); comp2.Add(&HRDepartment4); CFinanceDepartment FinanceDepartment4("杭州办事处财务部"); comp2.Add(&FinanceDepartment4); root.Add(&comp2); cout << endl << "结构图:" << endl; root.Display(1); cout << endl << "职责:" << endl; root.LineOfDuty(); system("pause"); return 0; }
输出结果: