1.组合模式又叫部分整体模式,他创建了对象组的树形结构,将对象组合成树状结构表示“整体-部分”的层次关系
2.组合模式依据树形结构来组合对象,用来表示部分以及整体层次
3.组合能让客户以一致的方式处理个别对象以及组合对象
原理结构图说明
1.Component:这是组合中的对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理Component 子部件,Component可以是抽象类或者抽象接口 2.Leaf:在组合中表示叶子节点,叶子节点没有字节点 3.Composite:非叶子节点,用于存储子部件,在Component接口中实现子部件的相关操作,比如add、remove等
1.组合模式解决这样的问题,当我们要处理的对象可以生成一颗树形结构,而我们要对树上的叶子节点进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子
编写程序展示一个学校的院系结构:要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系
思路图解
代码实现
package com.cedric.composite; 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(); } public OrganizationComponent(String name,String des){ this.name = name; this.des = des; } 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; } // 方法print,抽象 protected abstract void print(); }
package com.cedric.composite; import java.util.ArrayList; import java.util.List; // University 就是Composite,可以管理College public class University extends OrganizationComponent{ List<OrganizationComponent> organizationComponentList = new ArrayList<>(); // 构造器 public University(String name, String des) { super(name, des); } // 重写add @Override protected void add(OrganizationComponent organizationComponent) { organizationComponentList.add(organizationComponent); } //重写remove方法 @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponentList.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() + "==============="); // 便利List for(OrganizationComponent organizationComponent : organizationComponentList){ organizationComponent.print(); } } }
package com.cedric.composite; import java.util.ArrayList; import java.util.List; public class College extends OrganizationComponent{ // List中存放的是Department List<OrganizationComponent> organizationComponentList = new ArrayList<>(); // 构造器 public College(String name, String des) { super(name, des); } // 重写add @Override protected void add(OrganizationComponent organizationComponent) { // 实际业务中,College的add和University的add不一定完全一样 organizationComponentList.add(organizationComponent); } //重写remove方法 @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponentList.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() + "==============="); // 便利List for(OrganizationComponent organizationComponent : organizationComponentList){ organizationComponent.print(); } } }
package com.cedric.composite; public class Department extends OrganizationComponent{ public Department(String name, String des) { super(name, des); } // add 和 remove 不需要重写了,属于叶子节点 @Override public String getDes() { return super.getDes(); } @Override public String getName() { return super.getName(); } @Override protected void print() { System.out.println(getName()); } }
package com.cedric.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); computerCollege.print(); } }
1.简化客户端操作,客户端只需要面对一致的对象而不用考虑整体部分或叶子节点的问题 2.具有较强的扩展性,当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动 3.方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构 4.需要遍历组织结构,或者处理的对象具有树形结构时,非常适合组合模式 5.要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式