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

    重新看组合/合成(Composite)模式,发现它并不像自己想象的那么简单,单纯从整体和部分关系的角度去理解还是不够的,并且还有一些通俗的模式讲解类的书,由于其举的例子太过“通俗”,以致让人理解产生偏差,不过设计模式本身就是一种程序设计思想,不同的人当然会产生具有偏差性质的理解。

    GOF对组合模式的定义是:将对象组合成树形结构以表示“部分 -整体”的层次结构。 Composite使得用户对单个对象和组合对象的使用具有一致性 。这里,“用户对单个对象和组合对象的使用具有一致性”,这是Composite模式产生的效果。从表示形式来看,Composite表示的是“部分-整体”的关系,但是,往往忽略了效果。下图是Composite模式的结构图:

    Composite模式的对象结果如下:

    Composite类提供对Leaf类对象的管理方法,如Add(),Remove(),GetChild()方法,这些方法的定义可以有两种方法:一个是放在Component的顶层父类中,这样所有的子类(包括Leaf类)都会集成该方法,但Leaf类可以选择不实现这些方法;另外一个是将对Leaf对象操作的方法放到Composite类中,并不是放到Component类中。现在以GOF所著书中所给的例子为例,写出组合模式的代码,类图结构如下:

    代码如下:

     1 abstract class Graphic{
     2     
     3     public void Draw(){}
     4     public void Add(Graphic g){}
     5     public void Remove(Graphic g){}
     6     public Graphic GetChild(int index){return null;}
     7 }
     8 class Line extends Graphic{
     9     public void Draw(){
    10         System.out.println("Draw a Line");
    11     }
    12 }
    13 class Rectange extends Graphic{
    14     public void Draw(){
    15         System.out.println("Draw a Rectange");
    16     }
    17 }
    18 class Text extends Graphic{
    19     public void Draw(){
    20         System.out.println("Draw a Text");
    21     }
    22 }
    23 class Picture extends Graphic{
    24     private Vector<Graphic> vec=new Vector<Graphic>();
    25     public void Draw(){
    26         for(Graphic g : vec){
    27             g.Draw();
    28         }
    29     }
    30     public void Add(Graphic g){
    31         vec.add(g);
    32     }
    33     public void Remove(Graphic g){
    34         try{
    35             vec.remove(g);
    36         }catch(Exception e){
    37             
    38         }
    39     }
    40     public Graphic GetChild(int index){
    41         return vec.get(index);
    42     }
    43 }
    44 public class Test{
    45     public static void main(String[] args){
    46         Picture p=new Picture();
    47         p.Add(new Text());
    48         p.Add(new Rectange());
    49         p.Add(new Line());
    50         p.Draw();
    51         }
    52 }
    View Code

    适用Composite模式的情况:

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

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

    第一句话很好理解,第二句话该怎么理解呢?我的理解是,如果有一个方法Visist(Component con){con.Draw();}实现一个动作,这时候它并不需要知道是处理一个叶子结点对象还是一个组合对象,对于传进来的叶子结点对象,可以直接处理请求,如果是一个Composite,则将请求发给它的子部件,并且在转发请求之前/后还可以执行一些辅助操作。有人举过一个例子:文件和文件夹,该实现可以用组合模式,文件是Leaf,文件夹是Composite,我们可以单建文件对象,也可创建一个具有目录结构的文件夹对象,文件夹下面可以放文件对象,也可以放文件夹对象。

    为了提高系统的可复用性,有一些设计原则,其中有一条“组合/聚合复用原则”,就是优先使用“组合/聚合”,而非继承,这里说的组合是对象组合,也就是一个对象在运行时期动态获得其他对象的引用,从而达到不用继承而能扩展功能的效果;显然,对象组合的使用范围更大,和这里的组合模式不是同一个概念,前者毕竟是一个“设计原则”,而后者则是一个成型的“模式”,原则的使用范围当然更广了。

    通过今天的总结,对组合模式又有了进一步的认识,感谢GOF、《Java与模式》、《Thinking in Patterns》。

  • 相关阅读:
    Advanced Configuration Tricks
    Reviewing the Blog Module
    Editing and Deleting Data
    Making Use of Forms and Fieldsets
    Understanding the Router
    SQL Abstraction and Object Hydration
    Preparing for Different Databases
    Java学习理解路线图
    Openstack学习历程_1_视频
    CentOS安装Nginx负载
  • 原文地址:https://www.cnblogs.com/codeMedita/p/7354847.html
Copyright © 2011-2022 走看看