1.定义
组合多个对象形成树形结构以表示“整体-部分”的关系的层次结构。组合模式对叶子节点和容器节点的处理具有一致性,又称为整体-部分模式。
2.类图
角色与理解
组合模式共分为三种角色:
Component(抽象构件):叶子构件与容器构件共同继承的父类或者是共同实现的接口,该角色中包含所有子类共有方法的声明和实现,在抽象构件中定义了管理子构件的方法,新增构件、删除构件、获取构件。
Leaf(叶子构件):表示叶子节点,没有子节点,对于继承父类的管理子节点的方法以抛出异常的方式处理。
Composite(容器构件):表示容器节点,包含子节点,子节点可以是容器节点也可以是叶子节点,其提供一个集合来对子节点进行维护,以迭代的方式对子节点进行处理。
组合模式的关键是抽象构件类,它既可以表示叶子节点也可以表示容器节点,对于客户端而言是统一对抽象构件进行处理的,抽象构件类和容器构件类是聚合关联的关系,抽象构件类是容器构件类的一部分,这样容器构件类对子构件进行处理时不用区分是叶子节点还是容器节点,能够统一的做处理。
3.实验题
在该教育机构的OA系统中可以给各级办公室下发公文,现采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。
(1) 抽象组件类
import java.util.ArrayList;
//抽象构建类
abstract class Componnent{
private String name;
abstract void receiveDoc();
public String getName(){
return this.name;
}
public void sendDoc(Componnent componnent){
}
}
(2)叶子节点
//叶子节点(行政办公室)
class xzbgs extends Componnent{
private String name;
xzbgs(String name){
this.name=name;
}
public String getName(){
return this.name;
}
void receiveDoc(){
System.out.println("行政办公室收到文件");
}
}
//叶子节点(教务办公室)
class jwbgs extends Componnent{
private String name;
jwbgs(String name){
this.name=name;
}
public String getName(){
return this.name;
}
void receiveDoc(){
System.out.println("教务办公室收到文件");
}
}
(3)容器节点
//容器节点
class container extends Componnent{
private ArrayList<Componnent> list;
private String name;
container(String name){
this.name=name;
}
void receiveDoc(){
System.out.println(this.name+"收到文件");
}
Componnent getChild(int n){
return list.get(n);
}
void add(Componnent componnent){
list.add(componnent);
}
void remove(Componnent componnent){
list.remove(componnent);
}
public String getName(){
return this.name;
}
public void sendDoc(Componnent componnent){
System.out.println(name+"发送文件到"+componnent.getName());
componnent.receiveDoc();
}
}
(4)测试类
public class Test {
public static void main(String[] args) {
Componnent a1=new xzbgs("行政办公室");
Componnent a2=new jwbgs("教务办公室");
Componnent b1=new container("北京总部");
Componnent b2=new container("湖南分校");
Componnent b3=new container("长沙教学点");
Componnent b4=new container("湘潭教学点");
b1.sendDoc(b2);
b1.sendDoc(a1);
b1.sendDoc(a2);
b2.sendDoc(b3);
b2.sendDoc(b4);
b3.sendDoc(a1);
b3.sendDoc(a2);
b4.sendDoc(a1);
b4.sendDoc(a2);
}
}