1.定义
允许你将对象组合成树形结构来表现“整体/部分”层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。
2.模式介绍
2.1.模式中的角色
定义中描述的组合能让客户一致的方式来处理个别对象及对象组合,其中我们使用抽象组件来做到一致的方式,使用叶子节点来处理个别对象,使用容器节点来处理对象组合。
- 抽象构件(Component)
抽象组件可以是抽象类或者接口。 - 叶子构件(Leaf)
叶子构件为没有子节点。 - 容器构件(Composite)
容器构件有子节点,子节点可以是叶子构件或者容器构件。
2.2.类图
3.测试代码
抽象容器
/**
* 抽象构件
*/
public interface Component {
void add(Component component);
void remove(Component component);
void operate();
List<Component> getChild();
}
叶子构件
/**
* 叶子构件
* 不支持add、remove、getChild等方法,此处直接抛出异常
*/
public class Leaf implements Component {
private String name;
Leaf(String name) {
this.name = name;
}
@Override
public void add(Component component) {
throw new UnsupportedOperationException("叶子节点不支持此方法");
}
@Override
public void remove(Component component) {
throw new UnsupportedOperationException("叶子节点不支持此方法");
}
@Override
public void operate() {
System.out.println(" this is leaf operate : " + name);
}
@Override
public List<Component> getChild() {
throw new UnsupportedOperationException("叶子节点不支持此方法");
}
}
容器构件
/**
* 容器构件
* 此处operate方法使用递归调用所有子节点的operate方法
*/
public class Composite implements Component {
List<Component> list = new ArrayList<>();
@Override
public void add(Component component) {
list.add(component);
}
@Override
public void remove(Component component) {
list.remove(component);
}
@Override
public void operate() {
operate(list);
}
private void operate(List<Component> childs) {
for (Component component : list) {
try {
component.operate();
} catch (Exception e) {
operate(component.getChild());
}
}
}
@Override
public List<Component> getChild() {
return list;
}
}
测试入口
public class InitMain {
public static void main(String[] args) {
/**
* 测试属性结构如下
* A
* / \
* leafA1 compositeB
* / \
* leafB compositeC
* / \
* leafC1 leafC2
*/
Component compositeA = new Composite();
Component leafA1 = new Leaf("leafA1");
compositeA.add(leafA1);
Component compositeB = new Composite();
Component leafB = new Leaf("leafB");
compositeB.add(leafB);
compositeA.add(compositeB);
Component compositeC = new Composite();
Component leafC1 = new Leaf("leafC1");
Component leafC2 = new Leaf("leafC2");
compositeC.add(leafC1);
compositeC.add(leafC2);
compositeB.add(compositeC);
//调用顶层容器构件的operate方法,打印所有构件的operate方法
compositeA.operate();
}
}
输出如下:
this is leaf operate : leafA1
this is leaf operate : leafB
this is leaf operate : leafC1
this is leaf operate : leafC2
4.总结
组合模式通过提供抽象构件通过树形结构达到让个别对象和容器对象能够使用一致的方式来解决问题。如果你想处理树形结构的对象集合或者想要忽略不通对象见的差异,就可以使用组合模式。
此模式中我们模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。