基本需求:
- 展示一个学校的结构,比如一个学校下面有多个学院,学院下面有多个系,相当于一个树形结构,对其节点需要进行操作
传统方案:
基本介绍:
-
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象
-
组合模式依据树形结构来组合对象,用来表示部分以及整体层次
-
这种类型的设计模式属于结构型模式,它创建了对象组的树形结构
-
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式
-
组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象
-
UML类图(原理)
-
UML类图(案例)
-
代码实现
-
@Data @AllArgsConstructor // 提供满参构造 强制子类提供满参构造 public abstract class OrganizationComponent { // 抽象层 Component 子类 Leaf (叶子节点) 和 Composite (非叶子节点) 都继承或实现该类 protected String name; protected String description; // 此处不定义成抽象方法的原因是避免叶子节点强制实现该方法(如果叶子节点很多) , 作为非叶子节点可以重写该方法 public void add(OrganizationComponent organizationComponent) { throw new UnsupportedOperationException(); } public void remove(OrganizationComponent organizationComponent) { throw new UnsupportedOperationException(); } public abstract void print(); }
-
public class University extends OrganizationComponent { // 此处作为第一层级的非叶子节点 实际聚合第二层级非叶子节点 用到了多态 private List<OrganizationComponent> collageList = new ArrayList<>(); public University(String name,String description) { super(name,description); } // 非叶子节点重写add和remove @Override public void add(OrganizationComponent organizationComponent) { this.collageList.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { this.collageList.remove(organizationComponent); } // 实现print方法 @Override public void print() { System.out.println("------------" + this.getName() + "------------"); this.collageList.forEach(OrganizationComponent::print); } }
-
public class Collage extends OrganizationComponent { // 此处作为第二层级的非叶子节点 实际聚合叶子节点 用到了多态 private List<OrganizationComponent> departmentList = new ArrayList<>(); public Collage(String name,description); } // 非叶子节点重写add和remove @Override public void add(OrganizationComponent organizationComponent) { this.departmentList.add(organizationComponent); } @Override public void remove(OrganizationComponent organizationComponent) { this.departmentList.remove(organizationComponent); } // 实现print方法 @Override public void print() { System.out.println("------------" + this.getName() + "------------"); this.departmentList.forEach(OrganizationComponent::print); } }
-
public class Department extends OrganizationComponent { // 此处作为非叶子节点 不需要重写 add 和 remove 方法(不支持) 使用这两个方法就会调用父类的抛出异常 public Department(String name,description); } @Override public void print() { System.out.println(this.getName()); } }
-
public class Client { public static void main(String[] args) { // 创建学校 OrganizationComponent university = new University("xx大学","xx大学"); // 创建学院 OrganizationComponent collage1 = new Collage("计算机学院","计算机学院"); OrganizationComponent collage2 = new Collage("信息工程学院","信息工程学院"); // 创建系 并将系加入到学院 collage1.add(new Department("软件工程","软件工程")); collage1.add(new Department("网络工程","网络工程")); collage2.add(new Department("通信工程","通信工程")); collage2.add(new Department("信息工程","信息工程")); // 将学院加入到学校 university.add(collage1); university.add(collage2); // 输出 university.print(); } }
-
jdk源码:
- jdk中的hashmap就使用到了组合模式
- UML类图
- 说明
- Map接口相当于Component类 中间多了一层抽象层AbstractMap,HashMap作为实现,Node类是HashMap的静态内部类(这样解释有点牵强)