组合模式(Composite):将对象组合成树形结构,以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
一、组合模式
组合模式又叫做部分-整体模式,常用来解决树型结构的问题。在下图所示的公司结构树中有工程部、人事部和下级子公司,这是一个典型的树形结构,可以利用组合模式描述公司的结构。
组合模式的UML图如下:
组合模式由以下部分组成:
抽象构件角色(Component):为组合中的对象声明接口, 在适当的情况下,也可实现所有类共有接口的缺省行为。声明一个接口用于访问和管理Component的子部件。
树叶构件角色(Leaf):在组合中表示叶节点对象,没有子节点,实现抽象构件角色声明的接口。
树枝构件角色(Composite):在组合中表示分支节点对象,有子节点,实现抽象构件角色声明的接口;存储子部件。
二、案列分析
我们用代码来实现开篇的公司结构。
代码部分:
Component类
abstract class Componment {
private String name;
private int depth;
public Componment(String name,int depth) {
this.name = name;
this.depth = depth;
}
public abstract void add(Componment c);
public abstract void remove(Componment c);
public abstract void display();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
}
Leaf 类
class Leaf extends Componment {
public Leaf(String name, int depth) {
super(name, depth);
}
@Override
public void add(Componment c) {
System.out.println("我是叶子节点,无法新增");
}
@Override
public void remove(Componment c) {
System.out.println("我是叶子节点,无法删除");
}
public void display() {
System.out.println(this.getName()+this.getDepth());
}
}
Composite 类:
class Composite extends Componment {
private List<Componment> children = new ArrayList<Componment>();
public Composite(String name, int depth) {
super(name, depth);
}
@Override
public void add(Componment c) {
children.add(c);
}
@Override
public void remove(Componment c) {
children.remove(c);
}
@Override
public void display() {
for (Componment c : children) {
c.display();
}
}
}
客户端测试:
public static void main(String[] args) {
Composite root = new Composite("root",1);
root.add(new Leaf("Leaf A",1));
root.add(new Leaf("Leaf B",1));
Composite comp1 = new Composite("comp1",2);
root.add(comp1);
comp1.add(new Leaf("Leaf C",2));
comp1.add(new Leaf("Leaf D",2));
Composite comp2 = new Composite("comp2",3);
comp2.add(new Leaf("Leaf E",3));
comp2.add(new Leaf("Leaf F",3));
comp1.add(comp2);
root.display();
}
运行结果:
代码地址:componment
以上代码部分 就展示了我们一开始的公司的树形结构图。
在使用组合模式中需要注意一点,也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。
三、模式结语
组合模式让我们能用树型方式创建对象的结构,树里面包含了Composite以及Leaf的对象。使用组合结构,我们能把相同的操作应用在Composite和Leaf上,即大多数情况下,我们可以忽略Composite和Leaf之间的差别,以相同的方式使用它们。为了保持透明性,Leaf和Composite都要继承或实现Component。
组合对象的关键在于它定义了一个抽象构建类,它既可表示叶子对象,也可表示容器对象,客户仅仅需要针对这个抽象构建进行编程,无须知道他是叶子对象还是容器对象,都是一致对待。
组合模式虽然能够非常好地处理层次结构,也使得客户端程序变得简单,但是它也使得设计变得更加抽象,而且也很难对容器中的构件类型进行限制,这会导致在增加新的构件时会产生一些问题。
欢迎大家留言评论,点击查看更多设计模式。