zoukankan      html  css  js  c++  java
  • 设计模式9——结构型模式之组合模式

    定义:组合模式(CompositePattern),将对象组合成树形结构以表示“部分—整体”的层次结构。“Composite”使得用户对单个对象和对组合对象的使用具有一致性。

    类型:结构型模式。

    类图:

    参与者:

    1. Computer,客户端,选择是否添加USB设备。
    1. USBDevice,所有USB设备的抽象类,提供USB设备的基本通信接口。
    1. USBMouse,单个对象,没有子部件。
    1. USBHub,也即Composite组合对象,可能存在多个子部件。

    适用性:

             无论是单个对象还是组合对象,用户都希望使用统一接口来控制,这种情况下适合组合模式。

    概述:

            组合模式给人的感觉很像树干树枝的结构,再一想,其实和USB拓扑结构图也一样(见下图)。主机,可以看作是ClientHub1可以看作是组合对象,包括两个USB设备以及一个新的组合设备Hub2.

     

           无论是USB设备还是USBHub,主机都可以通过相同的命令来访问它们。这也正是组合模式要完成的工作。即Client能够通过相同的接口来访问单个设备和组合设备。

    示例代码:

    1. #include <iostream>  
    2. #include <list>  
    3. using namespace std;  
    4.   
    5. // 抽象接口  
    6. class CUSBDevice  
    7. {  
    8. public:  
    9.     virtual ~CUSBDevice(){}  
    10.     virtual void Add(CUSBDevice* _pDev){}  
    11.     virtual void Remove(CUSBDevice* _pDev){}  
    12.     virtual void Transmit(){}  
    13.     virtual int GetChild(){return 0;}  
    14. };  
    15.   
    16. // 单一个对象,不能添加新部件  
    17. class CUSBMouse : public CUSBDevice  
    18. {  
    19. public:  
    20.     virtual void Transmit()  
    21.     {  
    22.         cout<<"传递鼠标移动点击信息"<<endl;  
    23.     }  
    24. };  
    25.   
    26. // 组合对象,可以添加多个新部件  
    27. class CUSBHub : public CUSBDevice  
    28. {  
    29. public:  
    30.     virtual void Add(CUSBDevice* _pDev)  
    31.     {  
    32.         m_listDev.push_back(_pDev);  
    33.     }  
    34.   
    35.     virtual void Remove(CUSBDevice* _pDev)  
    36.     {  
    37.         m_listDev.remove(_pDev);  
    38.     }  
    39.   
    40.     virtual void Transmit()  
    41.     {  
    42.         cout<<"传输USBHub信息"<<endl;  
    43.     }  
    44.   
    45.     virtual int GetChild()  
    46.     {  
    47.         return m_listDev.size();  
    48.     }  
    49. private:  
    50.     list<CUSBDevice*> m_listDev;  
    51. };  

     
    // 电脑主机先接了一个HubA,HubA再接了一个USB鼠标以及又一个USBHubB
    // USBHubB又接一个USB鼠标

    1. int _tmain(int argc, _TCHAR* argv[])  
    2. {  
    3.     // 先建立一个USBHub  
    4.     CUSBHub hubA;  
    5.     CUSBDevice* pUSBMA = new CUSBMouse;  
    6.     hubA.Add(pUSBMA);  
    7.   
    8.     // USBHubB  
    9.     CUSBDevice* pUSBHubB = new CUSBHub;  
    10.     CUSBDevice* pUSBMB = new CUSBMouse;  
    11.     pUSBHubB->Add(pUSBMB);  
    12.     hubA.Add(pUSBHubB);  
    13.   
    14.     // 移除设备  
    15.     if (pUSBMA->GetChild() > 0)  
    16.     {  
    17.         cout<<"移除设备"<<endl;  
    18.     }  
    19.   
    20.     delete pUSBMA;  
    21.     delete pUSBMB;  
    22.     delete pUSBHubB;  
    23.       
    24.     return 0;  
    25. }  

    注意:抽象基类的析构函数一定要是虚函数,否则内存释放的时候会有问题。

    优缺点:

    1. 优点,能够非常灵活地添加单个部件以及组合部件,不用区别对待单个对象以及组合对象。

    参考资料:

    1. 《设计模式——可复用面向对象软件基础》
    2. Java与模式》
    1. 《大话设计模式》
  • 相关阅读:
    你不知道的JS系列上( 40 ) - 什么是类
    CF356E
    [HDU4135]CO Prime(容斥)
    [POJ 2888]Magic Bracelet[Polya Burnside 置换 矩阵]
    Polya定理与Burnside引理
    选举
    David与Vincent的博弈游戏[树型DP]
    Vincent的城堡
    三元组
    vue打包体积优化之旅
  • 原文地址:https://www.cnblogs.com/feihe0755/p/3519638.html
Copyright © 2011-2022 走看看