二十三种设计模式(第九种)-----组合模式(Composite)
尚硅谷视频连接https://www.bilibili.com/video/BV1G4411c7N4?from=search&seid=11487053970269878470
- 组合模式,又叫部分整体模式,它创建了对象组的树行结构,将对象组合成树形结构以表示"整体-部分"的层次关系
- 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
- 这种类型的模式属于结构型模式。
- 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象
需求
看一个学校院系展示需求
编写程序展示一个学校院系结果:要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。
- 清华大学
- 计算机学院
- 计算机科学与计算
- 软件工程
- 网络工程
- 信息工程学院
- 通讯工程
- 信息工程
- 计算机学院
类图
代码
- 提取出的顶层类
@Data
@NoArgsConstructor
@AllArgsConstructor
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();
}
//方法print,做成抽象方法
protected abstract void print();
}
- 大学类
public class University extends OrganizationComponent {
List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
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();
}
//print输出University 包含的学院
@Override
protected void print() {
System.out.println("-----------"+getName()+"-----------");
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
}
- 学院类
public class College extends OrganizationComponent {
List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
public College(String name, String des) {
super(name, des);
}
//重新add
@Override
protected void add(OrganizationComponent organizationComponent){
//将来实际业务中,College的add和University中的add 不一定完全相同
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();
}
//print输出University 包含的学院
@Override
protected void print() {
System.out.println("-----------"+getName()+"-----------");
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
}
- 叶子节点 部门类
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());
}
}
- 客户端测试
public class Client {
public static void main(String[] args) {
//由大到小创建对象
//学校
OrganizationComponent university = new University("清华大学", "世界一流大学");
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();
}
}
HashMap中使用了组合模式
- Map就是一个抽象的构建(类似于我们的Component)
- HashMap是一个中间的构建(composite),实现/继承了相关方法
- Node是HashMap的静态内部类,类似于叶子节点
应用场景
- 需要遍历组织结构,或者处理的对象具有树形结构时,非常适合使用组合模式
- 要求较高的抽象性,如果节点和叶子节点有很多差异性的话,比如很多方法和属性都不一样的话,就不适合使用组合模式。