定义:
组合多个对象形成树形结构来表示“整体-部分”关系的层次结构,其中的叶子对象和容器对象具有相同的接口,可以使用抽象类来进行管理。
结构图:
- Component:抽象构件类,对叶子构件和容器构件声明抽象接口,包含它们所共有的行为和方法。同时也可以定义访问及管理它子构件的方法。
- Left:叶子构件,表示树形结构中的叶子节点,仅仅实现抽象构件类中定义的行为方法。因为没有子构件,对管理子构件的方法可以抛出异常处理。
- Composite:容器构件,包含子节点,其子节点可以是叶子节点,也可以是容器节点。对于行为方法,可以递归调用子节点的行为方法来完成业务;对应实现抽象构件中定义的管理子构件的方法。
两种模式:
对于抽象构件中既有构件行为方法和管理构件的方法,可以有两种解决方法。
透明模式:
- 将抽象构建类定义为抽象类,并为管理方法提供默认实现。
//提供默认实现的抽象构件类
abstract class AbstractFile {
public void add(AbstractFile file) {
System.out.println("对不起,不支持该方法!");
}
public void remove(AbstractFile file) {
System.out.println("对不起,不支持该方法!");
}
public AbstractFile getChild(int i) {
System.out.println("对不起,不支持该方法!");
return null;
}
public abstract void killVirus();
}
- 叶子构件继承该类时,不需要再重新实现管理方法;而容器构件则需要重新实现这些管理方法,并做覆盖。
- 客户端使用时,不能针对抽象接口编程;对于叶子节点,必需要使用具体叶子构件类型来定义叶子对象。
安全模式:
- 在抽象构件中仅定义行为方法,而不定义管理方法。客户端不会遇到叶子节点因为不存在方法而存在的异常。
- 但不能透明地使用容器构件,对容器构件需要特殊生命其类别。
优点:
- 可以表示比较复杂的树形关系,如果要新增叶子类和容器类都可以方便扩展。
- 统一了叶子构件和容器构件的接口,在执行业务方法时可以使用递归策略。
缺点:
- 难以避免在透明模式和安全模式中选择,但两种模式都有自己的缺点,使得客户端使用不透明。
- 不能限制容器下的叶子类型,所有的容器和叶子都依赖于一个接口。
适用情况:
- 需要构件一个树形结构的模式,可以区分整体和部分的差异,客户端可以一致地对待它们。
实例: