组合模式
概述
《设计模式》一书中对于 “组合模式” 的意图描述如下:
将对象组合成树形结构以表示 “部分—整体” 的层次结构,组合模式使得用户对单个对象和组合对象的的使用具有一致性
一般组合模式的 UML
图如下:
一般在以下情况中使用组合模式:
- 希望表示 “对象—整体” 的类结构层次
- 希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
具体实例
假设现在需要设计一个图形编辑器,其中的每个图像组件都能够被复用组合成为需要的组件,而这个新组成的组件又能够被其它组件引用,从而组合成为另一个新的组件。这种情况下就很适合使用组合模式来进行类的设计
首先定义所有组件都具备的公共接口 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();
}
}
再定义一些基本的常用组件:Line
、Circle
、Window
:
public class Line extends AbstracGraphic {
// .........
}
public class Circle extends AbstracGraphic {
// .........
}
对于组件 Window
来讲,它可以组合 Line
和 Circle
而形成新的组件类型:
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
不仅可以添加 Line
、Circle
,而且可以添加 Window
进一步丰富组件,使得不同的组件之间得到最大限度的复用
总结
通过组合模式,使得类的层次结构能够更加规整,在设计类结构时可以考虑
参考:
[1] 《设计模式—可复用面向对象基础》