组合模式
概念:今天,我们将学习23种设计模式的组合模式。组合模式主要用于组合多个对象形成树形结构,表示“整体-部分”的结构层次。
组合模式(Composite Pattern)又称部分-整体模式,是一种将对象组合成树状层次结构的模式,用于表示“部分-整体”之间的关系,使用户能够一致地访问单个对象和组合对象。组合模式根据树形结构组合对象,用于表示部分和整体层次。这种类型的设计模式属于结构设计模式。
特点:优点:
- 组合模式使客户端代码能够一致处理单个对象和组合对象,无需关心是单个对象还是组合对象,简化了客户端代码。
- 在组合中添加新对象很容易,客户端不会因为添加新对象而更改源代码,以满足“开关原则”。
缺点:
- 在使用组合模式时,叶子和树枝的声明是实现的,而不是接口,违反了依赖倒置的原则。
package cn.ppdxzz.composite;/** * Description:抽象类,默认行为实现所有类别的共同接口 */public abstract class OrganizationComponent { private String name;//名称 private String description;//描述 protected void add(OrganizationComponent organizationComponent) { ////默认实现 throw new UnsupportedOperationException(); } protected void remove(OrganizationComponent organizationComponent) { ////默认实现 throw new UnsupportedOperationException(); } //抽象方法,所有子类都需要实现 protected abstract void print(); public OrganizationComponent() { } public OrganizationComponent(String name, String description) { this.name = name; this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; }}
系别
package cn.ppdxzz.composite;/** * Description:系别 */public class Department extends OrganizationComponent { public Department(String name, String description) { super(name, description); } @Override public String getName() { return super.getName(); } @Override public String getDescription() { return super.getDescription(); } @Override protected void print() { System.out.println(getName()); }}
学院
package cn.ppdxzz.composite;import java.util.ArrayList;import java.util.List;/** * Description:学院 */public class College extends OrganizationComponent { ///List集合用于存储系统 List<OrganizationComponent> organizationComponents = new ArrayList<>(); public College(String name,String description) { super(name, description); } ///添加系别 @Override protected void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } ///移除系别 @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } //输出系别信息 @Override protected void print() { System.out.println("---" + getName() + "---"); organizationComponents.forEach(OrganizationComponent::print); } @Override public String getName() { return super.getName(); } @Override public String getDescription() { return super.getDescription(); }}
学校
package cn.ppdxzz.composite;import java.util.ArrayList;import java.util.List;/** * Description:学校 */public class University extends OrganizationComponent { //List集合存储College学院 List<OrganizationComponent> organizationComponents = new ArrayList<>(); public University(String name,String description) { super(name, description); } ///添加学院 @Override protected void add(OrganizationComponent organizationComponent) { organizationComponents.add(organizationComponent); } ///删除学院 @Override protected void remove(OrganizationComponent organizationComponent) { organizationComponents.remove(organizationComponent); } ///输出学院信息 @Override protected void print() { System.out.println("---" + getName() + "---"); organizationComponents.forEach(OrganizationComponent::print); } @Override public String getName() { return super.getName(); } @Override public String getDescription() { return super.getDescription(); }}
测试
package cn.ppdxzz.composite;/** * Description:组合模式(学校院系展示问题) */public class Client { public static void main(String[] args) { ///创建学校 OrganizationComponent university = new University("大学","大学很美"); ///创建学院 OrganizationComponent college1 = new College("电子信息工程学院","这是计算机学院"); OrganizationComponent college2 = new College("外语学院","这是外语学院"); ////在各学院下创建系 college1.add(new Department("计科系","它很强")); college1.add(new Department("电子系","它很强")); college2.add(new Department("英语系","这是英语系")); college2.add(new Department("韩语系","这是韩语系")); ///把学院加到学校 university.add(college1); university.add(college2); university.print(); }}
总结:- 简化客户端的操作。客户端只需要面对一致的对象,而不需要考虑整个部分或节点的叶子。
- 它具有很强的可扩展性。当我们想要改变组合对象时,我们只需要调整内部层次关系,客户端不需要做任何改变。
- 当需要遍历组织机构或处理的对象有树形结构时,非常适合使用组合模式。
- 如果节点和叶子之间存在许多差异,则组合模式需要较高的抽象性,如许多方法和属性不同,不适合使用组合模式。
- Java 的集合类 HashMap 组合模式在中间使用。
虽然组合模式可以清楚地定义不同层次的复杂对象,但也更容易添加新部件,但这导致系统设计更加抽象。如果系统的业务规则更加复杂,使用组合模式将面临一些挑战。
![](/images/780-200-2.jpg)