设计模式 c++版(16)—— 组合模式

定义:

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

组合模式也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要用来描述部分与整体的关系。


示例一:组合模式(通用版)

1. 类图21-6

2. 类图说明

Component:抽象构件角色。定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。
Leaf:叶子构件。叶子对象,其下再也没有其他分支,也就是遍历的最小单位。
Composite:树枝构建。树枝对象,它的作用是组合树枝节点和叶子节点形成的一个树形结构。


3.代码清单
 

#include <QCoreApplication>
#include <QDebug>

//////////////    **********  1.组合模式(通用版),代码清单21-1:***************//

//抽象构件
class Component
{
public:
    virtual void    doSomething(){qDebug() << "leaf";}
    virtual void    add(Component* component){}
    virtual bool    isLeaf() = 0;
};

//树枝构件
class Composite:public Component
{
public:
    void    add(Component* component)
    {
        this->m_component.push_back(component);
    }
    void    remove(Component* component)
    {
        this->m_component.removeOne(component);
    }
    QList<Component*>   getChildren()
    {
        return this->m_component;
    }
    virtual bool    isLeaf()
    {
        return false;
    }
    virtual void    doSomething()
    {
        if (!isLeaf())
        {
            QList<Component*> lists = getChildren();
            QList<Component*>::ConstIterator iter = lists.begin();
            while(iter != lists.end())
            {
                Component* component = *iter;
                component->doSomething();
                ++iter;
            }
        }
        qDebug() << "root";
    }

private:
    QList<Component*>   m_component;
};

//树叶构件
class Leaf:public Component
{
public:
    virtual bool    isLeaf()
    {
        return true;
    }
    virtual void    doSomething()
    {
        if (isLeaf())
        {
            Component::doSomething();
        }
    }
};

int main()
{
    Composite *root = new Composite();
    root->doSomething();
    
    Component *branch = new Composite();
    Component *leaf = new Leaf();

    root->add(branch);
    branch->add(leaf);
    
    root->doSomething();
    
    return 0;
}

三、组合模式的应用

1. 优点:

 高层模块调用简单。 一颗树形机构中的所有节点都是Component, 局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
 节点自由增加。使用了组合模式后,如果想增加一个树枝节点,树叶节点都很容易了,只要找到它的父节点就行,非常容易扩展,符合开闭原则,对以后的维护非常有利。

2. 缺点:

 组合模式有一个非常明显的缺点,使用时的定义,直接使用了实现类,在面向接口编程上很不恰当,与依赖倒置原则冲突,使用时候要考虑清楚,它限制了接口的影响范围。

3. 使用场景:

 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。
 从一个整体中能够独立出部分模块或功能的场景。

4. 注意事项:

只要是树形结构,就要考虑使用组合模式,只要是体现局部和整体的关系的时候,而且这种关系比较深,考虑一下组合模式。


四、最佳实践

组合模式在项目中到处都有,比如现在页面结构一般都是上下结构,上面放系统的logo,下面分为两部分:左边是导航菜单,右边是展示区,左边的导航菜单一般都是树形的结构,比较清晰,有非常多的javascript源码实现了类似的属性菜单。

大家常用的XML结构也是一个属性结构,根节点、元素节点、值元素这些都与我们的组合模式相匹配。

我们自己本身也是一个树状结构的树枝或树叶。根据我能够找到我的父母,根据父母可以找到爷爷奶奶,很典型的树形结构,且很规范。


参考文献《秦小波. 设计模式之禅》(第2版) (华章原创精品) 机械工业出版社

猜你喜欢

转载自blog.csdn.net/Jecklin_online/article/details/82908357