`

Design Pattern: Composite 模式

    博客分类:
  • J2SE
阅读更多

Composite模式定义:
将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

所以Composite模式使用到Iterator模式,和Chain of Responsibility模式类似。

Composite好处:
1.使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关系自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。

如何使用Composite?
首先定义一个接口或抽象类,这是设计模式通用方式了,其他设计模式对接口内部定义限制不多,Composite却有个规定,那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们(或称部件Component).

如果以绘图为例的话,一个文字是一个绘图元件,一个线段是一个绘图元件,而一个长方形也是一个绘图元件,这些绘图元件可以组成一个图片,如果将这个图片也视作一个绘图元件,则这么递回绘图下去,就可以组合成一个较大的、复杂的图形元件,这样的目的可以使用Composite模式来解决。

对于使用者而言,无论是文字、线段或长方形,甚至是组合后的图片元件,它们都拥有一个共同的行为,使用者基本上并不会感觉出它们之间的操作有任何的不同,您可以拖曳、放大、缩小等等,这些行为都是一致的。

下面的代码是以抽象类定义,一般尽量用接口interface,

public abstract class Equipment
{
  private String name;
  //实价
  public abstract double netPrice();
  //折扣价格
  public abstract double discountPrice();
  //增加部件方法  
  public boolean add(Equipment equipment) { return false; }
  //删除部件方法
  public boolean remove(Equipment equipment) { return false; }
  //注意这里,这里就提供一种用于访问组合体类的部件方法。
  public Iterator iter() { return null; }
  
  public Equipment(final String name) { this.name=name; }

抽象类Equipment就是Component定义,代表着组合体类的对象们,Equipment中定义几个共同的方法。

public class Disk extends Equipment
{
  public Disk(String name) { super(name); }
  //定义Disk实价为1
  public double netPrice() { return 1.; }
  //定义了disk折扣价格是0.5 对折。
  public double discountPrice() { return .5; }
}

Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。
还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有'儿子',这是树形结构中通常的情况,应该比较容易理解。现在我们先要定义这个组合体:

abstract class CompositeEquipment extends Equipment
{
  private int i=0;
  //定义一个Vector 用来存放'儿子'
  private Lsit equipment=new ArrayList();

  public CompositeEquipment(String name) { super(name); }

  public boolean add(Equipment equipment) {
     this.equipment.add(equipment);
     return true;
   }

  public double netPrice()
  {
    double netPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      netPrice+=((Equipment)iter.next()).netPrice();
    return netPrice;
  }

  public double discountPrice()
  {
    double discountPrice=0.;
    Iterator iter=equipment.iterator();
    for(iter.hasNext())
      discountPrice+=((Equipment)iter.next()).discountPrice();
    return discountPrice;
  }
  


  //注意这里,这里就提供用于访问自己组合体内的部件方法。
  //上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
  public Iterator iter()
  {
    return equipment.iterator() ;
  {
  //重载Iterator方法
   public boolean hasNext() { return i<equipment.size(); }
  //重载Iterator方法
   public Object next()
   {
    if(hasNext())
       return equipment.elementAt(i++);
    else
        throw new NoSuchElementException();
   }
  

}
 

上面CompositeEquipment继承了Equipment,同时为自己里面的对象们提供了外部访问的方法,重载了Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实现.

 

我们再看看CompositeEquipment的两个具体类:盘盒Chassis和箱子Cabinet,箱子里面可以放很多东西,如底板,电源盒,硬盘盒等;盘盒里面可以放一些小设备,如硬盘 软驱等。无疑这两个都是属于组合体性质的。

public class Chassis extends CompositeEquipment
{
   public Chassis(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}
public class Cabinet extends CompositeEquipment
{
   public Cabinet(String name) { super(name); }
   public double netPrice() { return 1.+super.netPrice(); }
   public double discountPrice() { return .5+super.discountPrice(); }
}
 

至此我们完成了整个Composite模式的架构。

我们可以看看客户端调用Composote代码:

Cabinet cabinet=new Cabinet("Tower");

Chassis chassis=new Chassis("PC Chassis");
//将PC Chassis装到Tower中 (将盘盒装到箱子里)
cabinet.add(chassis);
//将一个10GB的硬盘装到 PC Chassis (将硬盘装到盘盒里)
chassis.add(new Disk("10 GB"));

//调用 netPrice()方法;
System.out.println("netPrice="+cabinet.netPrice());
System.out.println("discountPrice="+cabinet.discountPrice());

 

上面调用的方法netPrice()或discountPrice(),实际上Composite使用Iterator遍历了整个树形结构,寻找同样包含这个方法的对象并实现调用执行.

Composite是个很巧妙体现智慧的模式,在实际应用中,如果碰到树形结构,我们就可以尝试是否可以使用这个模式。

以论坛为例,一个版(forum)中有很多帖子(message),这些帖子有原始贴,有对原始贴的回应贴,是个典型的树形结构,那么当然可以使用Composite模式,那么我们进入Jive中看看,是如何实现的.

Jive解剖
在Jive中 ForumThread是ForumMessages的容器container(组合体).也就是说,ForumThread类似我们上例中的 CompositeEquipment.它和messages的关系如图:
[thread]
   |- [message]
   |- [message]
      |- [message]
      |- [message]
         |- [message]

我们在ForumThread看到如下代码:


public interface ForumThread {
   ....
   public void addMessage(ForumMessage parentMessage, ForumMessage newMessage)
         throws UnauthorizedException;
   public void deleteMessage(ForumMessage message)
         throws UnauthorizedException;

  
   public Iterator messages();
      ....

}
 

类似CompositeEquipment, 提供用于访问自己组合体内的部件方法: 增加 删除 遍历.

 

分享到:
评论

相关推荐

    36种最新设计模式整理

    Design Pattern: Composite 模式 40 Design Pattern: Decorator 模式 41 Design Pattern: Facade 模式 44 Design Pattern: Flyweight 模式 46 Design Pattern: Proxy 模式(一) 48 Design Pattern: Proxy 模式(二...

    java设计模式源码-DesignPattern:设计模式(Java实现源码)

    DesignPattern项目是设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发...

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm”供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) 生成...

    单例模式源码java-DesignPattern:在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在

    DesignPattern 在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在源码中的使用,每种设计模式都举了一个简单的小例子来进行实现,并加以注释 包名解释 一、DesignPattern ...

    设计模式 design pattern

    1.1 什么是设计模式 2 1.2 Smalltalk MVC中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...

    java餐饮管理系统源码6-design_patterns:设计模式

    java餐饮管理系统源码6 design_patterns design_patterns 设计模式相关网站: Java设计模式书籍: ...组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 外观模式(Facade Pattern) 享元模式(Flywe

    uu-design-pattern:23种设计模式案例

    |- singleton 单例模式案例 |- structural(结构型模式) |- facade 外观模式案例 |- decorator 装饰器模式案例 |- adapter 适配器模式案例 |- flyweight 享元模式案例 |- composite 组合模式案例

    design-pattern-java.pdf

    桥接模式-Bridge Pattern 处理多维度变化——桥接模式(一) 处理多维度变化——桥接模式(二) 处理多维度变化——桥接模式(三) 处理多维度变化——桥接模式(四) 组合模式-Composite Pattern 树形结构的处理...

    Homework 2.1-1.doc

    The following class diagram represents a design in factory method pattern to query the features of different types of auto insurances. See the source code for the implementation of the following class...

    《Java Design Patterns》高清完整英文PDF版

    Learn how to implement design patterns in Java: each pattern in Java Design Patterns is a complete implementation and the output is generated using Eclipse, making the code accessible to all....

    深入浅出设计模式中文

    Head First Design Pattern 中文版本 1 Welcome to Design Patterns: an introduction 1 2 Keeping your Objects in the know: the Observer Pattern 37 3 Decorating Objects: the Decorator Pattern 79 4 Baking ...

    [源代码] 《易学 设计模式》 随书源代码

    第14章 如法炮制:组合模式 (Composite) 第15章 源源不断:享元模式 (Flyweight) 第16章 按部就班:模板方法模式 (TemplateMethod) 第17章 风吹草动:观察者模式 (Observer) 第18章 变化多端:状态模式 (State) 第19...

    C#设计模式-吕震宇

    C#设计模式(11)-Composite Pattern C#设计模式(10)-Adapter Pattern C#设计模式(9)-Prototype Pattern C#设计模式(8)-Builder Pattern C#设计模式(7)-Singleton Pattern C#设计模式(6)-Abstract ...

    Java.Design.Patterns.1537192353

    COMPOSITE PATTERN PROXY PATTERN FAÇADE PATTERN DECORATOR PATTERN FLYWEIGHT PATTERN TEMPLATE METHOD PATTERN MEDIATOR PATTERN CHAIN OF RESPONSIBILITY ... OBSERVER PATTERN STRATEGY PATTERN COMMAND ...

    Design.Patterns.Explained.Simply

    Composite Decorator Facade Flyweight Private Class Data Proxy Behavioral patterns Chain of Responsibility Command Interpreter Iterator Mediator Memento Null Object Observer State Strategy Template ...

    C#3.0设计模式.pdf

    1. C# Meets Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 About Patterns 2 About UML 3 About C# 3.0 5 About the Examples 6 2. Structural ...

    Design Patterns Elements of Reusable Object-Oriented Software

    • What Is a Design Pattern? • Design Patterns in Smalltalk MVC • Describing Design Patterns • The Catalog of Design Patterns • Organizing the Catalog • How Design Patterns Solve Design ...

    CoreJava-DesignPattern

    CoreJava-DesignPattern 创意设计模式 -- Abstract Factory - Done -- Builder - Done -- Factory Method -- Object Pool -- Prototype - Done -- Singleton - Done 结构设计模式 -- Adapter -- Bridge -- ...

    管理系统javasal源码-Design-Patterns-Demo:超全的设计模式——理论+实现demo

    管理系统java sal源码 [toc] 设计模式 ...Pattern)组合模式(Composite Pattern)装饰器模式(Decorator Pattern)外观模式(Facade Pattern)享元模式(Flyweight Pattern)代理模式(Proxy Pattern)

Global site tag (gtag.js) - Google Analytics