设计模式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. 《大话设计模式》
posted @ 2014-01-14 19:07  飞鹤0755  阅读(566)  评论(0编辑  收藏  举报