组合模式

概述

《设计模式》一书中对于 “组合模式” 的意图描述如下:

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

一般组合模式的 UML 图如下:

Composite.png

一般在以下情况中使用组合模式:

  • 希望表示 “对象—整体” 的类结构层次
  • 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象

具体实例

假设现在需要设计一个图形编辑器,其中的每个图像组件都能够被复用组合成为需要的组件,而这个新组成的组件又能够被其它组件引用,从而组合成为另一个新的组件。这种情况下就很适合使用组合模式来进行类的设计

首先定义所有组件都具备的公共接口 Graphic

public interface Graphic {
    void show(int x, int y); // 当前组件的显示位置
    void addGraphic(Graphic g); // 将另外一个图形组建 g 添加到当前的组件中
    void remove(Graphic g); // 移除当前组件中的对应组件
    Collection<Graphic> getAllChild(); // 获取当前组件中所有的子组件
}

定义一些基本的组件的公共父类 AbstractGraphic

public abstract class AbstracGraphic implements Graphic {
    void show(int x, int y){
        // 部分细节代码
    }
    
    void addGraphic(Graphic g) {
        throw new UnsupportedOperationException();
    }
    
    void remove(Graphic g) {
        throw new UnsupportedOperationException();
    }
    
    Collection<Graphic> getAllChild() {
        throw new UnsupportedOperationException();
    }
}

再定义一些基本的常用组件:LineCircleWindow

public class Line extends AbstracGraphic {
    // .........
}

public class Circle extends AbstracGraphic {
    // .........
}

对于组件 Window 来讲,它可以组合 LineCircle 而形成新的组件类型:

public class Window extends AbstracGraphic {
    private final Collection<Graphic> child = new ArrayList<>();
    
    @Override
    void show(int x, int y) {
        // ......
    }
    
    @Override
    void addGraphic(Graphic g) {
        child.add(g);
    }
    
    @Override
    void remove(Graphic g) {
        child.remove(g);
    }
    
    @Override
    Collection<Graphic> getAllChild() {
        return child;
    }
}

这样的 Window 不仅可以添加 LineCircle,而且可以添加 Window 进一步丰富组件,使得不同的组件之间得到最大限度的复用

总结

通过组合模式,使得类的层次结构能够更加规整,在设计类结构时可以考虑


参考:

[1] 《设计模式—可复用面向对象基础》

posted @ 2023-03-02 21:42  FatalFlower  阅读(16)  评论(0编辑  收藏  举报