设计模式九:composite(组合)——对象结构型模式
composite(组合)——对象结构型模式
1.意图
将对象组合成树形结构以表示“部分-整体”的层次结构,composite使得用户对单个对象和组合对象的使用具有一致性。
2.动机
用户可以组合多个简单组件以形成一些较大的组件,这些组件又可以组合成更大的组件。如果这些类的代码必须区分简单组件和容器,那么就会使程序更加复杂,而大多数情况下用户认为他们是一样的,composite模式描述了如何使用递归组合,使得用户不必对这些类进行区别。
3.适用性
你想表示对象的部分-整体层次结构
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
4.结构

参考:http://www.cnblogs.com/rosesmall/archive/2012/03/26/2418325.html
5.参与者
component
为组合中的对象声明接口
在适当的情况下,实现所有类共有接口的缺省行为
声明一个接口用于访问和管理component的自组建
(可选)在递归结构中定义一个接口,用于访问一个父部件,并在适当的情况下实现它
leaf
在组合中表示叶节点对象,叶节点没有子节点
在组合中定义图元对象的行为
composite
定义有子部件的那些部件的行为
存储子部件
在component接口中实现与子部件有关的操作
client
通过component接口操纵组合部件的对象
6.协作
用户使用component类接口与组合结构中的对象进行交互。如果接受者是一个叶节点,则直接处理请求,如果是一个composite,通常将请求发送给它的子部件,在转发之前或者之后可能执行一些辅助操作。
7.效果
1)定义了包含基本对象和组合对象的类层次结构
基本对象可以被组合成更复杂的组合对象,而这个对象又可以被组合,可以不断的递归下去。
2)简化客户代码
可以一致地使用组合结构和单个对象。用户不必担心处理的是一个叶节点还是一个组合节点
3)使得更容易增加新类型的组件
新定义的composite和leaf子类自动地与现有代码一起工作,客户程序不需要因为新的component类而改变
4)使你的设计变得更加一般化
8.实现
1)显式的父部件引用
保持从子部件到父部件的引用能简化组合结构的遍历和管理。通常在component内部定义父部件的引用。
对于父部件的引用,必须维护一个不变式,即一个组合的所有子节点以这个组合为父节点,而反之该组合以这些节点为子节点。保证这一点最简单的方式是,仅当一个组合中增加或者减少一个组件时,才改变这个组件的父部件。
2)共享组件
3)最大化component接口
尽可能的多为leaf和composite类定义一些接口
4)声明管理子部件的操作
在composite类还是在component类中声明这些操作,必须在安全性和透明性之间做出权衡。
5)component是否该实现一个component列表
6)子部件排序
7)使用高速缓冲存贮改善性能
8)应该由谁删除component
9)存贮组件最好用哪一种数据结构
9.代码示例
#include<iostream> #include<list> #include<string> #include<algorithm> using namespace std; class component { public: string name; virtual void add(component *c){}; virtual void show(){}; }; class leaf:public component { public: leaf(string str) { cout<<"a leaf is created"<<endl; name = str; } void show() { cout<<name<<endl; } }; class composite:public component { private: list<component*> elems; public: composite(string str) { cout<<"a composite is created"<<endl; name = str; } void add(component *c) { elems.push_back(c); } void show() { cout<<name<<endl; for(list<component*>::iterator iter = elems.begin(); iter!=elems.end(); iter++) { (*iter)->show(); } } }; int main() { composite *comp = new composite("comp1"); comp->add(new leaf("first leaf")); comp->add(new leaf("second leaf")); composite *c = new composite("a combo of three leafs"); c->add(new leaf("3rd leaf")); c->add(new leaf("4th leaf")); c->add(new leaf("5th leaf")); comp->add(c); cout<<endl<<"show the contents:"<<endl; comp->show(); }
10.相关模式
通常部件-父部件连接用responsibility of chain模式
decorator模式经常与component一起使用
flyweight让你共享组件,但是不能再引入他们的父部件
iterator可以用来遍历composite
visitor将本来应该分布在composite和leaf中的操作和行为局部化
浙公网安备 33010602011771号