组合模式的定义
组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
这种类型的设计模式属于结构型模式。
组合模式使得用户对单个对象和组合对象的访问具有一致性,即**:组合能让客户以一致的方式处理个别对象以及组合对象**。
组合模式的特点
组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点,树形结构图如下:
由上图可以看出,其实根节点和树枝节点本质上属于同一种数据类型,可以作为容器使用;而叶子节点与树枝节点在语义上不属于用一种类型。但是在组合模式中,会把树枝节点和叶子节点看作属于同一种数据类型(用统一接口定义),让它们具备一致行为。
这样,在组合模式中,整个树形结构中的对象都属于同一种类型,带来的好处就是用户不需要辨别是树枝节点还是叶子节点,可以直接进行操作,给用户的使用带来极大的便利。
组合模式的优缺点
优点:
缺点:
组合模式的结构
组合模式包含以下主要角色。
组合模式的结构图
完成 大学——学院——专业的展示
定义抽象构件(Component)角色:
public abstract class Component {
private String name;
private String des;
public Component(String name, String des) {
this.name = name;
this.des = des;
}
//增加
protected void add(Component component){
//抛出不支持操作的异常
throw new UnsupportedOperationException();
}
//移除
protected 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;
}
//抽象的打印方法
protected abstract void print();
}
定义树枝构件(Composite)角色 / 中间构件1:University 大学
public class University extends Component{
//List存放的是学院的信息
List<Component> components = new ArrayList<>();
public University(String name, String des) {
super(name, des);
}
@Override
protected void add(Component component) {
components.add(component);
}
@Override
protected void remove(Component component) {
components.remove(component);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
//打印University包含的学院的名字
@Override
protected void print() {
System.out.println("===============名称:"+getName()+"描述:"+getDes()+"===============");
for (Component coms : components){
coms.print();
}
}
}
定义树枝构件(Composite)角色 / 中间构件2:College 学院
public class College extends Component{
//List存放的是专业的信息
List<Component> components = new ArrayList<>();
public College(String name, String des) {
super(name, des);
}
//实际业务中,University和College重写的add方法和remove方法可能不相同
@Override
protected void add(Component component) {
components.add(component);
}
@Override
protected void remove(Component component) {
components.remove(component);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
//打印College包含的专业的名字
@Override
protected void print() {
System.out.println("===============名称:"+getName()+"描述:"+getDes()+"===============");
for (Component coms : components){
coms.print();
}
}
}
定义树叶构件(Leaf)角色:Department 专业
public class Department extends Component{
public Department(String name, String des) {
super(name, des);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println("名称:"+getName()+"描述:"+getDes());
}
}
编写测试类进行测试:
public class Client {
public static void main(String[] args) {
//创建大学
Component university = new University("清华大学", "非常好的大学");
//创建学院
Component college1 = new College("信息工程学院", "信息工程学院好多专业");
Component college2 = new College("建设工程学院", "建设工程学院好多专业");
//将学院添加到学校中
university.add(college1);
university.add(college2);
//创建专业,并把专业添加到学院中
college1.add(new Department("计算机科学与技术","计算机科学与技术好专业"));
college1.add(new Department("网络工程","网络工程好专业"));
college2.add(new Department("土木","土木好专业"));
college2.add(new Department("测绘","测绘好专业"));
university.print();
}
}