当前位置: 首页 > 图灵资讯 > 技术篇> 23种设计模式——组合模式

23种设计模式——组合模式

来源:图灵教育
时间:2023-12-12 13:46:27

组合模式

今天,我们将学习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 组合模式在中间使用。

虽然组合模式可以清楚地定义不同层次的复杂对象,但也更容易添加新部件,但这导致系统设计更加抽象。如果系统的业务规则更加复杂,使用组合模式将面临一些挑战。