通过理论,代码示例,Android源码来学习组合模式
介绍
组合模式(Composite Pattern)也称为部分整体模式 (Part Whole Pattern) ,属于结构性设计模式,组合模式比较简单,它将一组相似的对象看做一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此忽略掉对象与对象集合之间的差别。
定义
将对象组合成树形结构以表示 ”部分-整体“ 的层次结构,使得用户对整个对象和组合对象的使用具有一致性。
使用场景
- 表示对象的 ”部分-整体“ 层次结构时。
- 从一个整体中能够独立出部分模块或功能的场景。
UML 类图
- Component: 抽象根节点,为组合中的对象声明接口。在适当的情况下,实现所有类共有接口的缺省行为。声明一个接口用于访问和管理 Component 的子节点。可在递归结构中定义一个接口,用于访问一个父节点,并在合适的情况下实现它。
- Composite: 定义有子节点的那些枝干节点的行为,存储子节点,在 Component 接口中实现与子节点有关的操作。
- Leaf: 在组合中表示叶子节点对象,叶子节点没有子节点,在组合中定义节点对象的行为。
- Client: 通过 Component 接口操纵组合节点的对象。
代码示例
简单示例
抽象根节点:
1 | public abstract class Component { |
枝干节点:
1 | public class Composite extends Component { |
叶子节点:
1 | public class Leaf extends Component { |
test:
1 |
|
output:
1 | name: Root |
实战
业务背景: 用代码表示文件夹跟文件的组合关系;
文件和文件夹抽象类:
1 | public abstract class Dir { |
具体文件夹类:
1 | public class Folder extends Dir { |
具体文件类:
1 | public class File extends Dir { |
test:
1 |
|
output:
1 | sdcard ( |
这里我们以括号作为一个文件夹的内容范围,如上输出所以 adcard 下文件夹有 3 个子文件夹 Android、baidu、downloads 子文件夹,以及一个 bug.log 文件,而在 3 个子文件夹中还各自包含子文件夹和文件,一个典型的树状嵌套解耦,这就是一个组合模式。
总结
优点:
- 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让高层模块忽略了层次的差异,方便对整个层次结构进行控制。
- 高层模块可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了高层模块的代码。
- 在组合模式中增加了新的枝干构件和叶子构件都很方便,无须对现有类库进行任何修改,符合 “开闭原则”。
- 组合模式为树状结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和树干对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
缺点:
早新增构件时不好对树干中的构件类型进行限制,不能依赖类型系统来施加这些约束,因为在大多数情况下,它们都来自于想听的抽象层,此时,必须进行类型检查来实现,这个实现过程较为复杂。