在现实生活中,存在很多"部分-整体"的关系,他们通常都可以用树形结构来表示。比如:大学中的学院与系、军队中的军士结构、公司中的部门分级情况还有文件系统中的文件与文件夹。我们可以将系统中的一个文件夹看成一个容器对象,它包含了多个文件和文件夹,子文件夹中又可以包含多个文件和文件夹。
而文件夹(容器对象)和文件(叶子对象)在功能上有所区别,这使得我们在使用的过程中需要区分容器对象和叶子对象,但大多数情况下,我们希望能在使用的过程中不需要区分二者,而是能够对叶子对象和容器对象的进行一致性使用。
组合(Composite Pattern)模式的定义:组合模式又叫作整体-部分模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对叶子对象和组合对象(容器对象)的使用具有一致性
组成(角色) | 作用 |
---|---|
Component(抽象构件) | 它可以是接口或抽象类,是叶子节点和容器节点的共同父类。包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。 |
Leaf(叶子构件) | 它表示叶子节点对象,叶子节点没有子节点,因此叶子节点在实现抽象构件中有关操作子节点的方法时,比如add(),remove()等方法时,可以让方法抛出异常,也可以实现为空操作。 |
Composite(容器构件) | 它表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它的主要作用是存储和管理子构件,通常包含 Add()、Remove()、GetChild() 等方法 |
子构件表示的就是子节点,所以子构件包括叶子节点和容器节点
//抽象构件,是叶子构件和容器构件的共同接口
public abstract class Component {
// name是名称,des是描述
public String name;
public String des;
public Component(String name, String des) {
setName(name);
setDes(des);
}
// 抽象方法,叶子节点和容器节点都需要实现
public abstract void show();
public void add(Component component) {
throw new UnsupportedOperationException();
}
public void remove(Component component) {
throw new UnsupportedOperationException();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
}
// 导包
import java.util.ArrayList;
import java.util.List;
// 容器构件1:University
public class University extends Component {
// List用来装College
// Component引用的是College实例
List<Component> children = new ArrayList<Component>();
public University(String name, String des) {
super(name, des);
}
// 重写父类add方法,添加College实例
public void add(Component component) {
children.add(component);
}
// 重写父类remove方法,删除College实例
public void remove(Component component) {
children.remove(component);
}
// 打印List中的所有元素,会逐级调用show()方法
// University调用College中的show()方法,College又调用Major中的show()方法
public void show() {
System.out.println("--"+getName()+"--");
for(Component e:children){
e.show();
}
}
}
import java.util.ArrayList;
import java.util.List;
// 容器构件1:College
public class College extends Component {
// List用来装Major
// Component引用的是Major实例
List<Component> children = new ArrayList<Component>();
public College(String name, String des) {
super(name, des);
}
// 重写父类add方法,添加Major实例
public void add(Component component) {
children.add(component);
}
// 重写父类add方法,删除Major实例
public void remove(Component component) {
children.remove(component);
}
// 打印List中的所有元素,会逐级调用show()方法
// 先通过调用自身getName()方法打印自己的name,然后在增强for中调用的是Major中的show()方法
public void show() {
System.out.println("--" + getName() + "--");
for (Component e : children) {
e.show();
}
}
}
//叶子构件:没有子节点,只需要重写父类的抽象方法show()
public class Major extends Component{
public Major(String name,String des){
super(name,des);
}
//父类的抽象方法,需要重写
public void show() {
System.out.println(getName());
}
}
public class Client {
public static void main(String[] args) {
Component university = new University("迦骊惇大学", "一流名校");
// 创建金融学院,会计学院,工程学院
Component finance = new College("金融学院", "一流专业");
Component accounting = new College("会计学院", "一流专业");
Component engineering = new College("工程学院", "一流专业");
// 为金融学院添加:投资,金融专业
finance.add(new Major("投资学", "一级学科"));
finance.add(new Major("金融学", "一级学科"));
// 为会计学院添加:会计,财务专业
accounting.add(new Major("会计学", "一级学科"));
accounting.add(new Major("财务学", "一级学科"));
// 为工程学院添加:计科,信管专业
engineering.add(new Major("计科", "一级学科"));
engineering.add(new Major("信管", "一级学科"));
// 将三个学院添加到大学university中
university.add(finance);
university.add(accounting);
university.add(engineering);
university.show();
}
}
/*
* 迦骊惇大学 金融学院 投资 金融 会计学院 会计 财务 工程学院 计科 信管
*/
//执行结果
--迦骊惇大学--
--金融学院--
投资学
金融学
--会计学院--
会计学
财务学
--工程学院--
计科
信管