一、基本概念
1.1 定义
组合模式将一组看似相似的对象看作一个对象处理,并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此 忽略掉对象与对象集合 之间的差别。
将对象组合成树形结构以表示 "部分-整体" 的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
1.2 Demo
- 定义基类的方法
/**
* 基类。
*/
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
/**
* 定义抽象方法。
*/
public abstract void doSomething();
/**
* 添加子节点。
*
* @param component
*/
public abstract void addChild(Component component);
/**
* 移除子节点。
*
* @param component
*/
public abstract void removeChild(Component component);
}
- 枝干节点
/**
* 组合对象,包含叶子对象。
*/
public class Composite extends Component {
/**
* 叶子对象的集合。
*/
private List<Component> mComponents;
public Composite(String name) {
super(name);
mComponents = new ArrayList<>();
}
@Override
public void doSomething() {
for (Component component : mComponents) {
component.doSomething();
}
}
@Override
public void addChild(Component composite) {
mComponents.add(composite);
}
@Override
public void removeChild(Component composite) {
mComponents.remove(composite);
}
}
- 叶子节点
/**
* 叶子对象。
*/
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void doSomething() {
Log.d("Leaf", name + "- doSomething");
}
@Override
public void addChild(Component component) {
}
@Override
public void removeChild(Component component) {
}
}
- 客户类
public class Simulator {
public static void simulate() {
Component leaf = new Leaf("leaf1");
Component leaf2 = new Leaf("leaf2");
Component component = new Composite("composite1");
component.addChild(leaf);
component.addChild(leaf2);
Component leaf3 = new Leaf("leaf3");
Component leaf4 = new Leaf("leaf4");
Component component2 = new Composite("composite2");
component2.addChild(leaf3);
component2.addChild(leaf4);
component.doSomething();
component2.doSomething();
}
}
1.3 应用场景
表示对象的 部分-整体 层次结构时。
从一个 整体 中能够独立出 部分模块或功能 的场景。
1.4 组合模式的优缺点
优点
- 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让高层模块 忽略了层次的差异,方便对整个层次结构进行结构控制。
- 高层模块可以 一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了高层模块的代码。
- 在组合模式中增加新的枝干构件和叶子构件都很方便,无须对现有的类库进行任何修改,符合 开闭原则。
- 为树形结构的面向对象提供了一种灵活的解决方案,通过叶子对象和枝干对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
缺点
- 在新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统来施加这些约束,因为在大多数情况下,它们都来自于相同的抽象层。
二、Android 源码
组合模式在Android
源码中最经典的例子就是View
和ViewGroup
的嵌套组合。
三、项目应用
待补充。