zoukankan      html  css  js  c++  java
  • 组合模式

    1.概念

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

    2.角色

      1)Component是组合中的对象声明接口,在适当情况下实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

      2)Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

      3)Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

    3.适用性

      以下情况下适用Composite模式:

      1)你想表示对象的部分-整体层次结构

      2)你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

    4.效果及实现要点

      1)Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转化“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

      2)将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复内部实现结构——发生依赖关系,从而更能“应对变化”。

      3)Composite模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊结构,这又是必须付出的代价。ASP.NET控件的实现在这方面为我们提供了一个很好的示范。

      4)Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

    5.总结  

      组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以向处理简单元素一样来处理复杂元素。如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。

    6.代码

     1 #include "stdafx.h"
     2 #include <iostream>
     3 #include <string>
     4 #include <vector>
     5 using namespace std;
     6 
     7 class Component
     8 {
     9 public:
    10   string m_strName;
    11   Component(string strName)
    12   {
    13     m_strName = strName;
    14   }
    15   virtual void Add(Component* com)=0;
    16   virtual void Display(int nDepth)=0;
    17 };
    18 
    19 class Leaf : public Component
    20 {
    21 public:
    22   Leaf(string strName): Component(strName){}
    23 
    24   virtual void Add(Component* com)
    25   {
    26     cout<<"leaf can't add"<<endl;
    27   }
    28   virtual void Display(int nDepth)
    29   {
    30     string strtemp;
    31     for(int i=0; i < nDepth; i++)
    32     {
    33       strtemp+="-";
    34     }
    35     strtemp += m_strName;
    36     cout<<strtemp<<endl;
    37   }
    38 };
    39 
    40 class Composite : public Component
    41 {
    42 private:
    43   vector<Component*> m_component;
    44 public:
    45   Composite(string strName) : Component(strName){}
    46 
    47   virtual void Add(Component* com)
    48   {
    49     m_component.push_back(com);
    50   }
    51 
    52   virtual void Display(int nDepth)
    53   {
    54     string strtemp;
    55     for(int i=0; i < nDepth; i++)
    56     {
    57       strtemp+="-";
    58     }
    59     strtemp += m_strName;
    60     cout<<strtemp<<endl;
    61 
    62     vector<Component*>::iterator p=m_component.begin();
    63     while (p!=m_component.end())
    64     {
    65       (*p)->Display(nDepth+2); 
    66       p++;
    67     }
    68   }
    69 };
    70 
    71 //客户端
    72 int main()
    73 {
    74   Composite *p=new Composite("总经理");
    75   Composite *pM=new Composite("技术部门经理");
    76   p->Add(pM);
    77   pM->Add(new Leaf("开发人员A"));
    78   pM->Add(new Leaf("开发人员B"));
    79   Composite *pS=new Composite("销售部门经理");
    80   p->Add(pS);
    81   pS->Add(new Leaf("销售人员C"));
    82   pS->Add(new Leaf("销售人员D"));
    83   p->Display(1);
    84 
    85   system("pause");
    86   return 0;
    87 }

  • 相关阅读:
    组合,封装与多态
    继承与派生
    面向对象基础练习
    面向对象基础
    类与对象
    数组与pandas模块
    Flask基础(15)-->模板代码的复用【宏(Macro)、继承(Block)、包含(include)】
    Flask基础(14)-->自定义过滤器
    Flask基础(13)-->Flask扩展Flask-Script
    Flask基础(12)-->请求上下文和应用上下文
  • 原文地址:https://www.cnblogs.com/SnailProgramer/p/4286007.html
Copyright © 2011-2022 走看看