标签:
1.概念
将对象组合成树形结构以表示”部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
2.角色
1)Component是组合中的对象声明接口,在适当情况下实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
2)Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。
3)Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。
3.适用性
以下情况下适用Composite模式:
1)你想表示对象的部分-整体层次结构
2)你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
4.效果及实现要点
1)Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。
2)将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。
3)Composite模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。ASP.NET控件的实现在这方面为我们提供了一个很好的示范。
4)Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。
5.总结
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。
6.代码
1 #include "stdafx.h" 2 #include <iostream> 3 #include <string> 4 #include <vector> 5 using namespace std; 6 7 class Component 8 { 9 public: 10 string m_strName; 11 Component(string strName) 12 { 13 m_strName = strName; 14 } 15 virtual void Add(Component* com)=0; 16 virtual void Display(int nDepth)=0; 17 }; 18 19 class Leaf : public Component 20 { 21 public: 22 Leaf(string strName): Component(strName){} 23 24 virtual void Add(Component* com) 25 { 26 cout<<"leaf can‘t add"<<endl; 27 } 28 virtual void Display(int nDepth) 29 { 30 string strtemp; 31 for(int i=0; i < nDepth; i++) 32 { 33 strtemp+="-"; 34 } 35 strtemp += m_strName; 36 cout<<strtemp<<endl; 37 } 38 }; 39 40 class Composite : public Component 41 { 42 private: 43 vector<Component*> m_component; 44 public: 45 Composite(string strName) : Component(strName){} 46 47 virtual void Add(Component* com) 48 { 49 m_component.push_back(com); 50 } 51 52 virtual void Display(int nDepth) 53 { 54 string strtemp; 55 for(int i=0; i < nDepth; i++) 56 { 57 strtemp+="-"; 58 } 59 strtemp += m_strName; 60 cout<<strtemp<<endl; 61 62 vector<Component*>::iterator p=m_component.begin(); 63 while (p!=m_component.end()) 64 { 65 (*p)->Display(nDepth+2); 66 p++; 67 } 68 } 69 }; 70 71 //客户端 72 int main() 73 { 74 Composite *p=new Composite("总经理"); 75 Composite *pM=new Composite("技术部门经理"); 76 p->Add(pM); 77 pM->Add(new Leaf("开发人员A")); 78 pM->Add(new Leaf("开发人员B")); 79 Composite *pS=new Composite("销售部门经理"); 80 p->Add(pS); 81 pS->Add(new Leaf("销售人员C")); 82 pS->Add(new Leaf("销售人员D")); 83 p->Display(1); 84 85 system("pause"); 86 return 0; 87 }
标签:
原文地址:http://www.cnblogs.com/SnailProgramer/p/4286007.html