基本需求:
传统方案:
基本介绍:
-
组合模式(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的静态内部类(这样解释有点牵强)
注意事项:
- 简化客户端操作,客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题
- 具有较强的扩展性,当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动
- 方便创建出复杂的层次结构,客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构
- 需要遍历组织机构,或者处理的对象具有树形结构时,非常适合使用组合模式
- 要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。