业务场景:
传统的解决方案:(使用继承的方式)
传统方案解决学校院系展示问题分析
1)将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的
2)实际上我们的要求是 :在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系, 因此这种方案,不能很好实现的管理的操作,比如 对学院、系的添加,删除,遍历等
3)解决方案:把学校、院、系都看做是组织结构,他们之间没有继承的关系,而是 一个树形结构,可以更好的实现管理操作。 => 组合模式
组合模式基本介绍
基本介绍
1) 组合模式(CompositePattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以 表示“整体-部分”的层次关系。
2) 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
3) 这种类型的设计模式属于结构型模式。
4) 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象
组合模式原理图:
对原理结构图的说明-即(组合模式的角色及职责)
- component:这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理component子部件,component可以是抽象类或者接口。
- Leaf:在组合中表示叶子节点,叶子节点没有子节点。
- Composite:非叶子节点,用哦关于存储子部件,在component接口中实现子部件的相关操作,比如增加、删除等。
代码:
component部分
package com.composite; public abstract class OrganizationComponent { private String name;//名字 private String des;//说明 //构造器 public OrganizationComponent(String name, String des) { this.name = name; this.des = des; } protected void add(OrganizationComponent organizationComponent){ //添加默认实现 throw new UnsupportedOperationException(); } protected void remove(OrganizationComponent organizationComponent){ //添加默认实现 throw new UnsupportedOperationException(); } //打印方法,做成抽象的,因为子类都需要实现 protected abstract void print(); 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; } }
composite部分:
package com.composite; import java.util.ArrayList; import java.util.List; /** * 大学 */ public class University extends OrganizationComponent { //list 中存放的是 college 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); } //重写getName @Override public String getName() { return super.getName(); } //重写getDes @Override public String getDes() { return super.getDes(); } //重写print @Override protected void print() { System.out.println("-----------"+getName()+"------------"); //遍历organizationComponents for (OrganizationComponent organizationComponent : organizationComponents) { organizationComponent.print(); } } }
package com.composite; import java.util.ArrayList; import java.util.List; public class College extends OrganizationComponent { //list 中存放的是 department List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>(); //构造器 public College(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); } //重写getName @Override public String getName() { return super.getName(); } //重写getDes @Override public String getDes() { return super.getDes(); } //重写print @Override protected void print() { System.out.println("-----------"+getName()+"------------"); //遍历organizationComponents for (OrganizationComponent organizationComponent : organizationComponents) { organizationComponent.print(); } } }
leaf部分:
package com.composite; import java.util.ArrayList; import java.util.List; /** * 专业 */ public class Department extends OrganizationComponent { //构造器 public Department(String name, String des) { super(name, des); } //add remove 方法就不用写了,因为他是叶子节点,下面不包含任何东西了 //重写getName @Override public String getName() { return super.getName(); } //重写getDes @Override public String getDes() { return super.getDes(); } //重写print @Override protected void print() { System.out.println(getName()); } }
client部分:
package com.composite; 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(); //或者,我们只想打印计算机学院的信息 //computerCollege.print(); } }
运行结果:
-----------清华大学------------ -----------计算机学院------------ 软件工程 网络工程 计算机科学与技术工程 -----------信息工程学院------------ 通信工程 信息工程
组合模式在 JDK 集合的源码分析
package com.composite; import java.util.HashMap; import java.util.Map; /** * 组合模式在 JDK 集合的源码分析 * 1) Java 的集合类-HashMap 就使用了组合模式 * * 2) 代码分析+Debug 源码 * * */ public class Composite { public static void main(String[] args) { /** * 1.Map 就是一个抽象的构造(类似我们的Component) * 2.HashMap 是一个中间的构建(Composite),实现了相关方法 put putAll * 3.Node 是HashMap的静态内部类,类似leaf叶子节点,这里没有put putAll 等方法 */ Map<Integer, String> hashMap = new HashMap<>(); hashMap.put(0,"东游记"); Map<Integer, String> map = new HashMap<>(); map.put(1,"西游记"); map.put(2,"红楼梦"); hashMap.putAll(map); System.out.println(hashMap); } }
运行结果:{0=东游记, 1=西游记, 2=红楼梦}