设计模式九: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中的操作和行为局部化

 

posted @ 2012-05-19 20:27  w0w0  阅读(327)  评论(0)    收藏  举报