zoukankan      html  css  js  c++  java
  • 设计模式 Composite

    设计模式 -- Composite 
     

    作用:

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

        UML结构图:



        抽象基类:

        1)Component:为组合中的对象声明接口,声明了类共有接口的缺省行为(如这里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component的子组件。

        接口函数:

        1)Component:Operatation:定义了各个组件共有的行为接口,由各个组件的具体实现。

        2)Component:Add添加一个子组件

        3)Component:Remove::删除一个子组件。

        4)Component:GetChild:获得子组件的指针。

        解析:

        Component模式是为解决组件之间的递归组合提供了解决的办法,它主要分为两个派生类,其中的Leaf是叶子结点,也就是不含有子组件的结点,而Composite是含有子组件的类。举一个例子来说明这个模式,在UI的设计中,最基本的控件是诸如Button,Edit这样的控件,相当于是这里的Leaf组件,而比较复杂的控件比如List则可也看做是由这些基本的组件组合起来的控件,相当于这里的Composite,它们之间有一些行为含义是相同的,比如在控件上作一个点击,移动操作等等的,这些都可以定义为抽象基类中的接口虚函数,由各个派生类去实现之,这些都会有的行为就是这里的Operation函数,而添加,删除等进行组件组合的操作只有非叶子结点才可能有,所以虚拟基类中只是提供接口而且默认的实现是什么都不做。

    实现:

        1)Composite.h

    #ifndef COMPOSITE_H
    #define COMPOSITE_H

    #include <list>

    // 组合中的抽象基类
    class Component
    {
    public:
        Component(){}
        virtual ~Component(){}

        // 纯虚函数,只提供接口,没有默认的实现
        virtual void Operation() = 0;

        // 虚函数,提供接口,有默认的实现就是什么都不做
        virtual void Add(Component* pChild);
        virtual void Remove(Component* pChild);
        virtual Component* GetChild(int nIndex);
    };

    // 派生自Component,是其中的叶子组件的基类
    class Leaf
        : public Component
    {
    public:
        Leaf(){}
        virtual ~Leaf(){}

        virtual void Operation();
    };

    // 派生自Component,是其中的含有子件的组件的基类
    class Composite
        : public Component
    {
    public:
        Composite(){}
        virtual ~Composite();

        virtual void Operation();

        virtual void Add(Component* pChild);
        virtual void Remove(Component* pChild);
        virtual Component* GetChild(int nIndex);

    private:
        // 采用list容器去保存子组件
        std::list<Component*>    m_ListOfComponent;
    };

    #endif

     

    2)Composite.cpp

    #include "Composite.h"
    #include <iostream>
    #include <algorithm>


    void Component::Add(Component* pChild)
    {

    }

    void Component::Remove(Component* pChild)
    {

    }

    Component* Component::GetChild(int nIndex)
    {
        return NULL;
    }


    void Leaf::Operation()
    {
        std::cout << "Operation by leafn";
    }


    Composite::~Composite()
    {
        std::list<Component*>::iterator iter1, iter2, temp;

        for (iter1  = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.end();
             iter1 != iter2;
             )
        {
            temp = iter1;
            ++iter1;
            delete (*temp);
        }
    }

    void Composite::Add(Component* pChild)
    {
        m_ListOfComponent.push_back(pChild);
    }

    void Composite::Remove(Component* pChild)
    {
        std::list<Component*>::iterator iter;

        iter = find(m_ListOfComponent.begin(), m_ListOfComponent.end(), pChild);

        if (m_ListOfComponent.end() != iter)
        {
            m_ListOfComponent.erase(iter);
        }
    }

    Component* Composite::GetChild(int nIndex)
    {
        if (nIndex <= 0 || nIndex > m_ListOfComponent.size())
            return NULL;

        std::list<Component*>::iterator iter1, iter2;
        int i;
        for (i = 1, iter1  = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.end();
            iter1 != iter2;
            ++iter1, ++i)
        {
            if (i == nIndex)
                break;
        }

        return *iter1;
    }

    void Composite::Operation()
    {
        std::cout << "Operation by Compositen";

        std::list<Component*>::iterator iter1, iter2;

        for (iter1  = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.end();
            iter1 != iter2;
            ++iter1)
        {
            (*iter1)->Operation();
        }
    }

    3)Main.cpp

    #include "Composite.h"
    #include <stdlib.h>

    int main()
    {
        Leaf *pLeaf1 = new Leaf();
        Leaf *pLeaf2 = new Leaf();

        Composite* pComposite = new Composite;
        pComposite->Add(pLeaf1);
        pComposite->Add(pLeaf2);
        pComposite->Operation();
        pComposite->GetChild(2)->Operation();

        delete pComposite;

        system("pause");

        return 0;
    }

  • 相关阅读:
    nginx配置二级目录,反向代理不同ip+端口
    一次实验环境中的数据库空间整理经历
    NFine中权限判断出错的问题
    Centos7 硬盘分区
    12个必备的JavaScript装逼技巧
    判断五大浏览器类型
    npm 常用命令及版本号浅析
    js 判断IE浏览器
    娱乐冷门小知识
    vue baidu Map 百度路书去掉动画
  • 原文地址:https://www.cnblogs.com/wzh206/p/1690795.html
Copyright © 2011-2022 走看看