学校院系展示需求
编写程序展示一个学校院系结构:类似下图
1.使用组合模式
使用继承关系不能很好的实现管理的操作。
解决方案:把学校、院、系都看作组织结构,他们之间没有继承的关系,而是一个树形结构,可以更好地实现管理操作。
2.组合模式基本介绍
- 组合模式,又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
- 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
- 这种类型的设计模式属于结构型模式。
- 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。
3.组合模式类图
- Component :组合中的对象声明接口,在适当的情况下,实现所有类共有的接口默认行为,用于访问和管理Component子部件,Component可以是抽象类或者接口。
- Leaf:在组合中表示叶子节点,叶子节点没有子节点。
- Composite:非叶子节点,用于存储子部件,在Component接口中实现子部件的相关操作,比如增加、删除
4.组合模式解决的问题
组合模式解决这样的问题,当我们要处理的对象可以生成一棵树形结构,而我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子。
5.组合模式解决学校问题
- OrganizationComponent就是对象声明接口,学校类、学院类、专业类都要继承这个类并且实现里面的方法。
- University、College是非叶子节点,内部聚合一个OrganizationComponent的实例(列表),用来存放低一层级的实例
- Department是叶子节点,内部无需聚合OrganizationComponent。
@Data
@NoArgsConstructor
@AllArgsConstructor
public abstract class OrganizationComponent {
private String name;
private String description;
protected void add(OrganizationComponent organizationComponent){
//默认实现,因为叶子节点不需要实现这个方法
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent){
//默认实现
throw new UnsupportedOperationException();
}
//做成抽象的
protected abstract void print();
}
//University可以管理College
public class University extends OrganizationComponent {
List<OrganizationComponent> organizationComponentList = new ArrayList<OrganizationComponent>();
//输出此University包含的学院
protected void print() {
System.out.println("-------"+getName()+"---------");
for (OrganizationComponent organizationComponent : organizationComponentList) {
organizationComponent.print();
}
}
public University(String name, String description) {
super(name, description);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponentList.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponentList.remove(organizationComponent);
}
}
public class College extends OrganizationComponent{
//存放的是Department
List<OrganizationComponent> organizationComponentList = new ArrayList<OrganizationComponent>();
//输出此University包含的学院
protected void print() {
System.out.println("-------"+getName()+"---------");
for (OrganizationComponent organizationComponent : organizationComponentList) {
organizationComponent.print();
}
}
public College(String name, String description) {
super(name, description);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponentList.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponentList.remove(organizationComponent);
}
}
//系
public class Department extends OrganizationComponent{
public Department(String name, String description) {
super(name, description);
}
//因为Department是叶子节点,所以不需要重写add,remove
protected void print() {
System.out.println(getName());
}
}
最后写Client类来调用,调用时只需要按以下步骤进行创建之后便可进行可各层级的查询。
public class Client {
public static void main(String[] args) {
//从大到小创建对象
//学校
OrganizationComponent university = new University("清华大学", "中国顶级大学");
//学院
OrganizationComponent computerCollege = new College("计算机学院","计算机");
OrganizationComponent informationCollege = new College("信息工程学院","信息工程");
//在学院中添加专业
computerCollege.add(new Department("软件工程","软件"));
computerCollege.add(new Department("网络工程","网络"));
computerCollege.add(new Department("计算机科学与技术","计科"));
informationCollege.add(new Department("通信工程","通信"));
informationCollege.add(new Department("信息工程","信息"));
//在学校中添加学院
university.add(computerCollege);
university.add(informationCollege);
university.print();
}
}
6.组合模式——HashMap
Map是一个接口,AbstractMap实现了Map接口,并且实现了默认的方法(比如put、putAll)。
Map与AbstractMap都相当于Component。
HashMap等相当于具体的composite,叶子节点即静态内部类Node。
7.组合模式小结
- 客户端只需要面对一致的对象而不用考虑整体部分或者叶子节点的问题。
- 具有较强的扩展性
- 方便创建出复杂的层次结构。
- 需要遍历组织结构,或者处理的对象具有树形结构时,非常适合使用组合模式。
- 要求有较高的抽象性,如果节点和叶子有很多差异的话,比如很多方法和属性不一致,不适合使用组合模式。