概念
就是在一个对象中包含其他对象,这些被包含的对象可能是终点对象(不再包含别的对象),也有可能是非终点对象(其内部还包含其他对象,或叫组对象),我们将对象称为节点,即一个根节点包含许多子节点,这些子节点有的不再包含子节点,而有的仍然包含子节点,以此类推。
举个例子
抽象组合对象
public abstract class Compositer {
private String name;
protected void setName(String name) {
this.name = name;
}
protected String getName() {
return name;
}
public abstract void add(Compositer com);
public abstract void remove(Compositer com);
public abstract Compositer getChild(int index);
public abstract void operation(); // 业务方法
}
child子对象
这里operation就循环遍历输出name
import java.util.ArrayList;
public class Child extends Compositer {
private ArrayList<Compositer> child;
public Child(String name) {
child = new ArrayList<>();
setName(name);
}
@Override
public void add(Compositer com) {
child.add(com);
}
@Override
public void remove(Compositer com) {
child.remove(com);
}
@Override
public Compositer getChild(int index) {
return index < child.size() ? child.get(index) : null;
}
//循环遍历输出名字
@Override
public void operation() {
System.out.println(getName());
if (child.size() > 0) {
for (Compositer item : child) {
item.operation();
}
}
}
}
leaf
叶子节点
public class Leaf extends Compositer {
public Leaf(String name) {
setName(name);
}
@Override
public void add(Compositer com) {
System.out.println("Can't do it");
}
@Override
public void remove(Compositer com) {
System.out.println("Can't do it");
}
@Override
public Compositer getChild(int index) {
System.out.println("Can't do it");
return null;
}
@Override
public void operation() {
System.out.println("This is a leaf " + getName());
}
}
客户端测试类
这里添加了一系列节点,形成了树状结构。
public class CompositeClient {
public static void main(String[] args) {
Child child1 = new Child("1");
Child child2 = new Child("2");
Child child3 = new Child("3");
Child child4 = new Child("4");
Child child5 = new Child("5");
Leaf leaf = new Leaf("叶子");
child1.add(child2);
child1.add(child3);
child2.add(child4);
child2.add(child5);
child2.add(leaf);
child1.operation();
}
}
结果如下:
End
当想表示对象的部分-整体层次结构(树形结构)或者希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象的时候,就可以选择使用组合模式。
优点: 高层模块调用简单、节点自由增加。
缺点: 在增加新构件时很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,比如只有叶子节点。这样就需要在添加时候动态判断。