定义
组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part-Whole)模式,它是一种对象结构型模式。
模式结构
角色职责
(1)抽象根节点(Component):定义系统各层次对象的共有方法和属性 ,可以预先定义一些默认行为和属性;
(2)树枝节点(Composite):定义树枝节点的行为 ,存储子节点 ,组合树枝节点和叶子节点形成一个树形结构;
(3)叶子节点(Leaf):叶子节点对象,其下再无分支,使系统层次便利的最小单位;
代码实现
组合模式在代码具体实现上,有两种不同的方式,分别是透明组合模式和安全组合模式。
透明组合模式
透明组合模式是把所有公共方法都定义在Component中,这样做的好处是客户端无需分辨是叶子节点(Leaf)和树枝节点(Composite),它们具备完全一致的接口。
抽象根节点:
/ 抽象根节点
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract String operation();
public boolean addChild(Component component) {
throw new UnsupportedOperationException("addChild not supported!");
}
public boolean removeChild(Component component) {
throw new UnsupportedOperationException("removeChild not supported!");
}
public Component getChild(int index) {
throw new UnsupportedOperationException("getChild not supported!");
}
}
树枝节点:
// 树节点
public class Composite extends Component {
private List<Component> mComponents;
public Composite(String name) {
super(name);
this.mComponents = new ArrayList<Component>();
}
@Override
public String operation() {
StringBuilder builder = new StringBuilder(this.name);
for (Component component : this.mComponents) {
builder.append("\n");
builder.append(component.operation());
}
return builder.toString();
}
@Override
public boolean addChild(Component component) {
return this.mComponents.add(component);
}
@Override
public boolean removeChild(Component component) {
return this.mComponents.remove(component);
}
@Override
public Component getChild(int index) {
return this.mComponents.get(index);
}
}
叶子节点:
//叶子节点
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public String operation() {
return this.name;
}
}
测试结果:
public class Test {
public static void main(String[] args) {
// 根节点
Component root = new Composite("root");
// 树枝节点
Component branchA = new Composite("---branchA");
Component branchB = new Composite("------branchB");
// 叶子节点
Component leafA = new Leaf("------leafA");
Component leafB = new Leaf("---------leafB");
Component leafC = new Leaf("---leafC");
root.addChild(branchA);
root.addChild(leafC);
branchA.addChild(leafA);
branchA.addChild(branchB);
branchB.addChild(leafB);
String result = root.operation();
System.out.println(result);
}
}
控制台打印结果:
root
---branchA
------leafA
------branchB
---------leafB
---leafC
安全组合模式
安全组合模式是只规定各个系统层次的最基础的一致行为,而把组合(树节点)本身的方法(管理子类对象的添加,删除等)放到自身当中。
此时顶层抽象组件Component类:
// 抽象根节点
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract String operation();
}
适用场景
1、在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
2、在一个使用面向对象语言开发的系统中需要处理一个树形结构。
3、在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
优缺点
优点:
1、清楚地定义分层次的复杂对象 ,表示对象的全部或部分层次
2、让客户端忽略了层次的差异 ,方便对整个层次结构进行控制
3、简化客户端代码
4、符合开闭原则
缺点:
1、限制类形时会较为复杂
2、使设计变得更加抽象