场景
编写程序展示一个学校的院系结构:
要在一个页面中展示出学校的院系组成 一个学校有多个学院 一个学院有多个系
如同一个树状结构一样管理多个对象
传统方案解决存在的问题
(1) 将学院看做是学校的子类 系是学院的子类 这样实际上是站在组织大小来进行分层次的
(2) 实际上的要求是: 在一个页面中展示出学校的院系组成 一个学校有多个学院 一个学院有多个系 因此这种方案 不能很好的实现管理的操作 比如对学院 系的添加 删除 遍历等
(3) 解决方案: 把学校 院 系都看做是组织结构 他们之间没有继承的关系 而是一个树形结构 可以更好的实现管理操作
介绍
(1) 组合模式(Composite Pattern) 也称部分整体模式 它创建了对象组的树形结构 将对象组合成树状结构以表示;"整体-部分"的层次关系
(2) 组合模式依据树形结构来组合对象 用来表示部分以及整体层次
(3) 这种类型地设计模式属于结构型模式
(4) 组合模式使得用户对单个对象和组合对象的访问具有一致性 即:组合能让客户以一致的方式处理个别对象以及组合对象
组合模式解决的问题
当我们要处理的对象可以生成一颗树形结构 而我们要对树上的节点和叶子进行操作时 它能够提供一致的方式 而不用去考虑它是节点还是叶子
代码演示
创建最顶层抽象类
@Data
public abstract class OrganizationComponent {
//名字
private String name;
//说明
private String des;
protected void add(OrganizationComponent org){
//默认实现
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent org){
//默认实现
throw new UnsupportedOperationException();
}
//方法 print 设置抽象 子类都需要实现该方法
protected abstract void print();
public OrganizationComponent(String name, String des) {
this.name = name;
this.des = des;
}
}
学校子类实现
public class University extends OrganizationComponent {
//聚合
List<OrganizationComponent> orgs = new ArrayList<>();
@Override
protected void add(OrganizationComponent org) {
orgs.add(org);
}
@Override
protected void remove(OrganizationComponent org) {
orgs.remove(org);
}
/**
* print方法 就是直接输入UNiversity包含的学院
*/
@Override
protected void print() {
System.out.println("============== "+ getName()+" ==================");
//遍历 orgs
orgs.forEach(item-> item.print());
}
public University(String name, String des) {
super(name, des);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
public void setName(String name) {
super.setName(name);
}
@Override
public void setDes(String des) {
super.setDes(des);
}
}
部门子类实现
public class Department extends OrganizationComponent{
@Override
protected void print() {
System.out.println("============== "+ getName()+" ==================");
System.out.println(getName());
}
public Department(String name, String des) {
super(name, des);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
public void setName(String name) {
super.setName(name);
}
@Override
public void setDes(String des) {
super.setDes(des);
}
}
测试
public static void main(String[] args) {
//从大到消创建对象 学校->学院->部门
//创建学校
OrganizationComponent university = new University("武汉大学","中国一流大学");
//创建学院
OrganizationComponent computeCpllege = new College("计算机学院","计算机系");
OrganizationComponent softwareCollege = new College("软件学院","计算机系");
//创建各个学院下面的系(专业)
computeCpllege.add(new Department("软件工程","软件工程很好"));
computeCpllege.add(new Department("电子信息科学","电子信息网络数据"));
computeCpllege.add(new Department("计算机科学与技术","很多人都喜欢报的专业"));
softwareCollege.add(new Department("软件技术","软件技术专业女生多哦"));
softwareCollege.add(new Department("通信工程","通信要学硬件的"));
//将学院加入到学校
university.add(computeCpllege);
university.add(softwareCollege);
System.out.println("学校所有信息");
university.print();
System.out.println("分割线------------------------------------------------------->");
System.out.println("计算机学院所有信息");
computeCpllege.print();
System.out.println("分割线------------------------------------------------------->");
}
组合模式的注意事项和细节
(1) 简化客户端的操作 客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题
(2) 具有较强的扩展性 当我们要更改组合对象时 我们只需要调整内部的层次关系 客户端不用做出任何改动
(3) 方便创建出复杂的层次结构 客户端不用理会组合里面的组成细节 容易调价节点或者叶子从而创建出复杂的树形结构
(4) 需要遍历组织结构 或者处理的对象具有树形结构时 非常是适合使用组合模式
(5) 要求较高的抽象性 如果节点和叶子有很多差异性的话 比如很多方法和属性都不一样 就不适合使用组合模式