模式意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使用户对单个对象和组合对象的使用具有一致性。
组合模式通常在java中的swing组件中体现的很明显,我们对中间节点容器jpanel或者对于叶子节点来说它们的使用方式具有一致性。
模式适用性
写程序时,我们希望将许多个体对象和组合对象组成树形结构,以此表示“部分-整体”的层次结构,并借助该层次结构使得用户能用一致的方式处理个体对象和组合对象。
模式参与者
- 抽象组件(Component):是一个接口(抽象类),该接口定义了个体对象和组合对象需要实现的关于操作其子节点的方法。
- Composite节点(Composite Node):实现Component 接口类的实例,Composite节点不仅实现Component接口,而且可以含有其他Composite节点或Leaf节点的引用。
- Leaf节点(Leaf Node):实现component接口类的实例,Leaf节点实现Component接口,不可以含有其他的Composite节点或Leaf的引用,因此,叶节点在实现Component接口的有关操作子节点的方法时,可让方法抛出一个异常,也可以实现为空操作。
其实在组合模式的参与者中composite节点和leaf节点基本上是一样的,区别是leaf节点同样都实现了component接口,但是接口中的具体方法实现为空。
举个例子来说明:
抽象组件(Component):MilitaryPerson.java
public interface MilitaryPerson {
public void add(MilitaryPerson person);
public void remove(MilitaryPerson person);
public MilitaryPerson getChild(int index);
public Iterator<MilitaryPerson> getAllChildren();
public boolean isLeaf();
public double getSalary();
public void setSalary();
}
Composite 节点:MilitaryOfficer
public class MilitaryOfficer implements MilitaryPerson{
LinkedList<MilitaryPerson> list;
String name;
double salary;
public MilitaryOfficer(String name,double salary) {
this.name = name;
this.salary = salary;
}
@Override
public void add(MilitaryPerson person) {
list.add(person);
}
@Override
public void remove(MilitaryPerson person) {
list.remove(person);
}
@Override
public MilitaryPerson getChild(int index) {
return list.get(index);
}
@Override
public Iterator<MilitaryPerson> getAllChildren() {
Iterator<MilitaryPerson> iterator = list.iterator();
return iterator;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public double getSalary() {
return salary;
}
@Override
public void setSalary() {
this.salary = salary;
}
}
Leaf节点
public class MilitarySoldier implements MilitaryPerson{
String name;
double salary;
public MilitarySoldier(String name,double salary) {
this.salary = salary;
this.name = name;
}
@Override
public void add(MilitaryPerson person) {
}
@Override
public void remove(MilitaryPerson person) {
}
@Override
public MilitaryPerson getChild(int index) {
return null;
}
@Override
public Iterator<MilitaryPerson> getAllChildren() {
return null;
}
@Override
public boolean isLeaf() {
return true;
}
@Override
public double getSalary() {
return salary;
}
@Override
public void setSalary() {
}
}
从上面例子可以使得对组合模式的理解更为深刻一点。
优点
- 组合模式中包含个体对象和组合对象,并形成树形结构,使用户可以方便的处理个体对象和组合对象
- 组合对象和个体对象实现了相同的接口,用户一般无须区分个体对象和组合对象。
- 增加新的Composite节点和Leaf节点时,用户的重要代码不需要做出修改。