zoukankan      html  css  js  c++  java
  • 面向对象设计模式之Composite组合模式(结构型)

    说明动机:
     * 在面向对象系统中,我们常常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时
     * ,又是其他对象的容器。例如:
     * public class SingleBox:IBox      public class ContainerBox:IBox
     * {                                {
     *   public void Process(){....}        public void Process(){....}
     * }                                                 public ArrayList GetBoxes(){....}
     *                                   }
     * 如何我们要对这样的对象容器进行处理:
     * IBox box=Factory.GetBox();
     * if(box is ContainerBOx)
     * {box.Process();ArrayList list=((ContainerBox)box).GetBoxes();...//将面临比较复杂的递归处理}
     * else if(box is SingleBox){box.Process();}
     * 这样的处理过程显然将其类结构过多的暴露给客户,而且让客户的代码依赖于对象容器复杂的内部实现结构;
     * 对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等
     * 弊端。如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客
     * 户代码就像处理简单对象一样来处理复杂的对象容器

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

    可适用性:

    • 你想表示对象的部分-整体层次结构。
    • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

    UML图解:

    示例代码:

      1 namespace Composite  //示例代码
      2 {
      3     /// <summary>
      4     /// 树容器对象接口
      5     /// </summary>
      6     public abstract class  IBox
      7     {
      8       
      9         public abstract void Process();
     10         public abstract void Add(IBox box);
     11         public abstract void Remove(IBox box);
     12         public abstract IBox GetChild(int index);
     13     }
     14 
     15     /// <summary>
     16     /// 单个容器(里面没有子容器)
     17     /// </summary>
     18     public class SingleBox : IBox
     19     {
     20 
     21         public override void Process()
     22         {
     23             //do something processing...
     24             
     25         }
     26 
     27         public override void Add(IBox box)
     28         {
     29             throw new NotSupportedException();
     30         }
     31 
     32         public override void Remove(IBox box)
     33         {
     34             throw new NotSupportedException();
     35         }
     36 
     37         public override IBox GetChild(int index)
     38         {
     39             return this;
     40         }
     41     }
     42 
     43     /// <summary>
     44     /// 容器(有子容器)
     45     /// </summary>
     46     public class ContainerBox : IBox
     47     {
     48         ArrayList boxList = null;
     49 
     50         public override void Process()
     51         {
     52             //do process for myself。。
     53             //......
     54             //do process for the box in boxList
     55             foreach (IBox item in boxList)
     56             {
     57                 item.Process();
     58             }
     59         }
     60 
     61         public override void Add(IBox box)
     62         {
     63             if (boxList == null)
     64             {
     65                 boxList = new ArrayList();
     66             }
     67             boxList.Add(box);
     68         }
     69 
     70         public override void Remove(IBox box)
     71         {
     72             boxList.Remove(box);
     73         }
     74 
     75         public override IBox GetChild(int index)
     76         {
     77             if (boxList == null)
     78             {
     79                 throw new  NullReferenceException();
     80             }
     81             else if (index < 0 || index > boxList.Count)
     82             {
     83                 throw new ArgumentOutOfRangeException();
     84             }
     85             return (IBox)boxList[index];
     86         }
     87     }
     88 
     89     public class App
     90     {
     91         public static void Main()
     92         {
     93             IBox box = new ContainerBox();
     94             box.Add(new SingleBox());
     95             box.Add(new ContainerBox());
     96 
     97             box.Process();//这样客户只需调用Process()方法就足够处理每个子容器了
     98         }
     99     }
    100 
    101    }


    Composite模式的几个要点 :

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

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

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

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

    注:本示例代码是本人学习Webcast C#面向对象设计模式纵横谈系列讲座视频时,跟着李建忠老师一步一步的编写的,在此奉献出来,仅供大家参考

    作者:JumpByte
    来源:http://www.cnblogs.com/yja9010
    更新: http://jumpbyte.cn
    声明:本博客原创文字只代表本人的观点或结论,于网站他人无关,非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    PHP-Manual的学习----【语言参考】----【基本语法】
    PHP-Manual的学习----【安装与配置】
    Python HTML解析模块HTMLParser(爬虫工具)
    Apache 配置方法(虚拟目录、域名、虚拟主机等)
    Apache httpd.conf配置文件主要内容解释
    Apache Windows下Apache安装步骤
    Apache Linux下Apache安装步骤
    【LOJ】#2055. 「TJOI / HEOI2016」排序
    【LOJ】#2054. 「TJOI / HEOI2016」树
    【LOJ】#2052. 「HNOI2016」矿区
  • 原文地址:https://www.cnblogs.com/yja9010/p/3178772.html
Copyright © 2011-2022 走看看