zoukankan      html  css  js  c++  java
  • 设计模式C++描述----11.组合(Composite)模式

    一. 举例

    这个例子是书上的,假设有一个公司的组结结构如下:


    它的结构很像一棵树,其中人力资源部和财务部是没有子结点的,具体公司才有子结点。

    而且最关健的是,它的每一层结构很相似。

    代码实现如下:
    1. //公司类,提供接口  
    2. class Company      
    3. {    
    4. public:    
    5.     Company(string name)  
    6.     {  
    7.         m_name = name;  
    8.     }    
    9.       
    10.     virtual ~Company()  
    11.     {}    
    12.       
    13.     virtual void Add(Company *pCom)  
    14.     {}    
    15.       
    16.     virtual void Display(int depth)  
    17.     {}  
    18.   
    19. protected:  
    20.     string m_name;    
    21. };  
    22.   
    23. //具体公司  
    24. class ConcreteCompany : public Company      
    25. {    
    26. public:    
    27.     ConcreteCompany(string name): Company(name)  
    28.     {}  
    29.   
    30.     virtual ~ConcreteCompany()  
    31.     {}  
    32.   
    33.     //增加子树或叶子  
    34.     void Add(Company *pCom)  
    35.     {  
    36.         m_listCompany.push_back(pCom);  
    37.     }  
    38.       
    39.     //显示  
    40.     void Display(int depth)  
    41.     {  
    42.         for(int i = 0;i < depth; i++)  
    43.         {  
    44.             cout<<"-";    
    45.           
    46.         }  
    47.           
    48.         cout<< m_name << endl;  
    49.           
    50.         list<Company *>::iterator iter = m_listCompany.begin();    
    51.           
    52.         for(; iter != m_listCompany.end(); iter++) //显示下层结点    
    53.         {      
    54.             (*iter)->Display(depth + 2);  
    55.         }  
    56.     }  
    57.   
    58. private:    
    59.     list<Company *> m_listCompany;    
    60. };    
    61.   
    62. //具体的部门,财务部    
    63. class FinanceDepartment : public Company     
    64. {  
    65. public:    
    66.     FinanceDepartment(string name):Company(name)  
    67.     {}    
    68.       
    69.     virtual ~FinanceDepartment()  
    70.     {}    
    71.       
    72.     //只需显示,无限添加函数,因为已是叶结点    
    73.     virtual void Display(int depth)  
    74.     {    
    75.         for(int i = 0; i < depth; i++)    
    76.             cout<<"-";    
    77.           
    78.         cout<< m_name << endl;  
    79.     }  
    80. };    
    81.   
    82. //具体的部门,人力资源部    
    83. class HRDepartment :public Company      
    84. {    
    85. public:    
    86.     HRDepartment(string name):Company(name)  
    87.     {}  
    88.       
    89.     virtual ~HRDepartment()  
    90.     {}  
    91.       
    92.     //只需显示,无限添加函数,因为已是叶结点    
    93.     virtual void Display(int depth)  
    94.     {  
    95.         for(int i = 0; i < depth; i++)    
    96.         {  
    97.             cout<<"-";  
    98.         }  
    99.         cout<< m_name << endl;    
    100.     }    
    101. };  
    102.   
    103. //////////////////////////////////////////////////////////////////////////  
    104. //测试代码  
    105. int main()  
    106. {  
    107.     Company *root = new ConcreteCompany("总公司");    
    108.     Company *leaf1=new FinanceDepartment("财务部");    
    109.     Company *leaf2=new HRDepartment("人力资源部");    
    110.     root->Add(leaf1);    
    111.     root->Add(leaf2);    
    112.    
    113.     //华东分公司  
    114.     Company *mid1 = new ConcreteCompany("华东分公司");    
    115.     Company *leaf3=new FinanceDepartment("华东分公司财务部");    
    116.     Company *leaf4=new HRDepartment("华东分公司人力资源部");    
    117.     mid1->Add(leaf3);  
    118.     mid1->Add(leaf4);  
    119.     root->Add(mid1);  
    120.       
    121.     //南京办事处  
    122.     Company *mid2=new ConcreteCompany("南京办事处");    
    123.     FinanceDepartment *leaf5=new FinanceDepartment("南京办事处财务部");    
    124.     HRDepartment *leaf6=new HRDepartment("南京办事处人力资源部");    
    125.     mid2->Add(leaf5);  
    126.     mid2->Add(leaf6);  
    127.     root->Add(mid2);  
    128.    
    129.     //杭州办事处  
    130.     Company *mid3=new ConcreteCompany("杭州办事处");    
    131.     FinanceDepartment *leaf7=new FinanceDepartment("杭州办事处财务部");    
    132.     HRDepartment *leaf8=new HRDepartment("杭州办事处人力资源部");    
    133.     mid3->Add(leaf7);    
    134.     mid3->Add(leaf8);    
    135.     mid2->Add(mid3);  
    136.   
    137.     root->Display(0);  
    138.   
    139.     delete leaf1;  
    140.     delete leaf2;    
    141.     delete leaf3;  
    142.     delete leaf4;    
    143.     delete leaf5;  
    144.     delete leaf6;  
    145.     delete leaf7;  
    146.     delete leaf8;    
    147.     delete mid1;  
    148.     delete mid2;    
    149.     delete root;    
    150.       
    151.     return 0;  
    152. }  

    二. 说明

    1. 上面公司的结构图其实就是整体与部分的关系,而且的话整体与部分可以一致对待,因为有很多相似之处嘛。

    2. 这棵树有两种几能,要么是棵叶,要么是子棵。

    其实这种模式就是组合模式。

    三. 组合模式

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

    要注意两点:

    1. “树形”,必须是一种层次结构,有可以向下延伸的分枝,也有不变的树叶。

    2. "一致性",也就是要具有很多相似性。

    结构图如下:

    component:主要是定义统一的接口,说白了也就是提取出相似性

    composite:定义分枝节点,也就是子树。

    leaf:定义叶节点,叶节点是没有子节点的。

  • 相关阅读:
    微信小程序里自定义组件,canvas组件没有效果
    微信小程序填坑之路(三):布局适配方案(rpx、px、vw、vh)
    小程序checkbox调整大小
    css让文字竖着排列 writing-mode 属性
    微信小程序 位置定位position详解,相对定位relative,绝对定位absolute相关问题
    小程序国际化实现方式
    mybatis plus 学习
    cesium js学习一加载三维模型【转】
    cesiumjs学习笔记之三——cesium-navigation插件 【转】
    局域网Cesium离线影像及瓦片影像地图加载【转】
  • 原文地址:https://www.cnblogs.com/any91/p/3247998.html
Copyright © 2011-2022 走看看