设计模式 - 复合模式(Composite pattern)【摘自 wikipedia 】

复合模式是一种分区设计模式。描述了一组对象,它们的处理方式与相同类型对象的单个实例相同。复合的目的是将对象“组合”成树结构以表示部分-整体层次结构。

实现复合模式,可以让客户端统一处理单个对象和组合。

 

哪些问题可以用复合设计模式解决?

  * 需要表示成部分-整体层次结构,以便客户端可以统一处理部分和整体对象;

  * 部分-整体层次结构需要表示成树结构。

注:定义(1)part 对象和(2)whole 充当 part 对象容器的对象时,客户端需要区别对待它们,使得客户端代码复杂化。

 

复合设计模式描述了什么解决方案?

  * Component 为部分 Leaf 对象和整体 Composite 对象定义统一接口;

  * 单个 Leaf 对象 Component 直接实现接口,Composite 对象将请求转发给它们的子组件。

  客户端可以通过 Component 接口统一对待 Leaf 和 Composite 对象。使得客户端类更易于实现、更改、测试、重用。

 

动机:

  处理树结构时,通常需要区分叶子结点和分支,使得代码复杂且易出错。解决方案是一个允许统一处理复杂和原始对象的接口。

  面向对象的编程中,组合是一个对象,被设计为一个或多个相似对象的组合,所有对象都表现出相似的功能。这被称为对象之间的“has-a”关系。

 

何时使用:

  当客户端忽略对象组合和单个对象之间的差异时,应该使用组合。如果程序员发现他们以相同的方式使用多个对象,并且经常有几乎相同的代码来处理每个对象,那么复合是一个不错的选择。在这种情况下,将原始的和复合的视为同构,并不复杂。

 

示例:UML 类和对象图

设计模式 - 复合模式(Composite pattern)【摘自 wikipedia 】

 

 定义与子相关的操作

设计模式 - 复合模式(Composite pattern)【摘自 wikipedia 】

  存在 2 种设计变体,用于定义和实现与子组件相关的操作,例如在容器中添加/删除/访问子组件

    * 统一性设计:在 Component 接口中定义与子相关的操作,使得客户端能统一对待 Leaf 、Composite 对象。但是类型安全丢失了,因为客户端可以对 Leaf 对象执行与子相关的操作。

    * 类型安全设计:仅在 Composite 类中定义与子相关的操作。

  注:复合设计模式强调一致性而不是类型安全。

 

 UML 类图

设计模式 - 复合模式(Composite pattern)【摘自 wikipedia 】

   Component 

    * 所有组件的抽象,包括复合组件

    * 声明组合中对象的接口

    * (可选)定义一个用于访问递归结构中组件父级的接口,并在适当时实现它

  Leaf

    * 表示组合中的叶对象

    * 实现所有组件方法

  Composite

    * 表示一个复合组件(有子组件的组件)

    * 实现操作孩子的方法

    * 实现所有Component方法,通常是通过将它们委托给它的孩子

 

 Java 代码示例

import java.util.List;
import java.util.ArrayList;

/** "Component" */
interface Graphic {
    //Prints the graphic.
    public void print();
}

/** "Composite" */
class CompositeGraphic implements Graphic {
    //Collection of child graphics.
    private final List<Graphic> childGraphics = new ArrayList<>();

    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        childGraphics.add(graphic);
    }
    
    //Prints the graphic.
    @Override
    public void print() {
        for (Graphic graphic : childGraphics) {
            graphic.print();  //Delegation
        }
    }
}

/** "Leaf" */
class Ellipse implements Graphic {
    //Prints the graphic.
    @Override
    public void print() {
        System.out.println("Ellipse");
    }
}

/** Client */
class CompositeDemo {
    public static void main(String[] args) {
        //Initialize four ellipses
        Ellipse ellipse1 = new Ellipse();
        Ellipse ellipse2 = new Ellipse();
        Ellipse ellipse3 = new Ellipse();
        Ellipse ellipse4 = new Ellipse();

        //Creates two composites containing the ellipses
        CompositeGraphic compositGraphic2 = new CompositeGraphic();
        compositGraphic2.add(ellipse1);
        compositGraphic2.add(ellipse2);
        compositGraphic2.add(ellipse3);
        
        CompositeGraphic compositGraphic3 = new CompositeGraphic();
        compositGraphic3.add(ellipse4);
        
        //Create another graphics that contains two graphics
        CompositeGraphic compositGraphic = new CompositeGraphic();
        compositGraphic.add(compositGraphic2);
        compositGraphic.add(compositGraphic3);

        //Prints the complete graphic (Four times the string "Ellipse").
        compositGraphic.print();
    }
}

 

上一篇:SSIS 优化设计1:数据源的提取和使用暂存


下一篇:opencv ellipse