继续打卡设计模式
今天来聊一下组合模式
一、提出一个实际问题
我们现在有一个学校,里面涵盖了学院,学院下面又分为各个子专业。那么现在如何方便的来管理查看这些学校学院专业的对应关系呢。
对于传统不用设计模式一般的做法无非把学校想象成一个集合,学院为这个学校集合的各个元素,其中学院元素又是一个集合,这个集合中包含了多个专业。那么这样看我们就是需要三个类以及对应容器来承载,假如后面需要添加学院在往集合中添加元素。
首先这种方式对于处理这个需求来说肯定是可行的。又回到一个场景了。谈设计模式一定是对代码的优化,我们肯定是想着以后的需求增加或者变更时如何不修改原有代码的情况下继续对原有功能的增加或删除。
现在我们如果增加一个类,这个专业下面继续分各个班级,或者在学院与专业之间在增加一个层级叫做二级学院
好比:
清华大学 -> 信息学院 -> 电子信息工程专业
清华大学 -> 信工学院 -> 电子信息学院 ->电子信息工程专业
好比以上这种结构。我们现在可能传统做法依然是添加类
二、组合模式来解决
谈起组合模式又叫做整体模式、它创建了对象组的树形结构。将对象组合成树状结构以表示整体-部分的层次关系,使得用户对单个对象和组合对象的访问具有一致性。组合能让用户以一致的方式处理个别对象以及组合对象。
首先我们有一个组织结构类,抽象类里面包含一个抽象对象的名称和描述
现在为了接下来方便测试我们写一个print方法。
/**
* @author: 德鑫
* Description: 这个是一个组织类
* @Date: 2021/01/20
*/
public abstract class OrganizationComponent {
private String name;
private String des;
protected void add(OrganizationComponent organizationComponent) {
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent) {
throw new UnsupportedOperationException();
}
public OrganizationComponent(String name, String des) {
this.name = name;
this.des = des;
}
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;
}
//方法print, 做成抽象的, 子类都需要实现
protected abstract void print();
}
/**
* @author: 德鑫
* Description:
* @Date: 2021/01/20
*/
public class University extends OrganizationComponent {
List<OrganizationComponent> organizationComponents = new ArrayList<>();
public University(String name, String des) {
super(name, des);
}
// 重写add
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponents.add(organizationComponent);
}
// 重写remove
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println("******" + getName() + "******");
//遍历 organizationComponents
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
}
/**
* @author: 德鑫
* Description:
* @Date: 2021/01/20
*/
public class College extends OrganizationComponent {
List<OrganizationComponent> organizationComponents = new ArrayList<>();
public College(String name, String des) {
super(name, des);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponents.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println("--------------" + getName() + "--------------");
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
}
/**
* @author: 德鑫
* Description: 部门
* @Date: 2021/01/20
*/
public class Department extends OrganizationComponent {
public Department(String name, String des) {
super(name, des);
}
//add , remove 就不用写了,在树形结构中它是叶子节点
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println( getName() );
}
}
最后写一个客户端来测试
/**
* @author: 德鑫
* Description: 组合模式又叫整体模式。它创建了对象组的树形结构。将对象组合成树状结构以表示整体-部分的层次关系
*
* 组合模式依据树形结构来组合对象,用来表示部分已经整体层次。
* 组合模式使得用户对单个对象和组合对象的访问具有一致性。组合能让用户以一致的方式处理个别对象以及组合对象。
* @Date: 2021/01/20
*/
public class Client {
public static void main(String[] args) {
//从大到小创建对象 学校
OrganizationComponent university = new University("qinghua","top1");
//创建 学院
OrganizationComponent computerCollege = new College("计算机学院", " 计算机学院 ");
OrganizationComponent infoEngineercollege = new College("信息工程学院", " 信息工程学院 ");
//创建各个学院下面的系(专业)
computerCollege.add(new Department("软件工程", " 软件工程不错 "));
computerCollege.add(new Department("网络工程", " 网络工程不错 "));
computerCollege.add(new Department("计算机科学与技术", " 计算机科学与技术是老牌的专业 "));
infoEngineercollege.add(new Department("通信工程", " 通信工程不好学 "));
infoEngineercollege.add(new Department("信息工程", " 信息工程好学 "));
university.add(computerCollege);
university.add(infoEngineercollege);
university.print();
}
}