设计模式(8/23) - 组合模式

59 阅读3分钟

组合模式

1 概述

  • 组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。
  • 组合模式通过递归组合的方式,使得客户端可以以统一的方式处理单个对象和组合对象,从而简化了客户端代码。

2 优缺点及应用场景

2.1 优点

  • 1)清晰的层次结构:组合模式使得客户端可以一致地处理单个对象和组合对象,树形结构清晰直观。
  • 2)简化客户端代码:客户端可以一致地使用组合模式中的对象,无需区分处理单个对象还是组合对象。
  • 3)便于扩展:可以方便地向组合中添加新的节点。

2.2 缺点

  • 1)可能导致复杂性增加:过度使用组合模式可能导致系统变得复杂。
  • 2)对子类依赖较大:组合模式中对子类的依赖较大,增加了子类的实现难度。

2.3 应用场景

  • 1)表示层次结构的对象:适用于需要表示树形结构的场景,例如文件系统、组织结构图等。
  • 2)统一处理单个对象和组合对象:需要客户端统一处理单个对象和组合对象的场景。

3 结构

  • 1)组件(Component):定义组合对象和叶子对象的接口。
  • 2)叶子(Leaf):实现组件接口的叶子节点对象,叶子节点没有子节点。
  • 3)组合(Composite):实现组件接口的组合对象,组合对象包含子节点,可以是叶子节点或其他组合对象。

4 实现

4.1 UML 类图

组合模式.jpg

4.2 代码示例

// 创建 Employee 类,该类带有 Employee 对象的列表
class Employee {
  private String name;
  private String dept;
  private int salary;
  private List<Employee> subordinates;

  // 构造函数
  public Employee(String name, String dept, int sal) {
    this.name = name;
    this.dept = dept;
    this.salary = sal;
    subordinates = new ArrayList<Employee>();
  }

  public void add(Employee e) {
    subordinates.add(e);
  }

  public void remove(Employee e) {
    subordinates.remove(e);
  }

  public List<Employee> getSubordinates() {
    return subordinates;
  }

  @NonNull
  public String toString() {
    return ("Employee :[ Name : " + name
        + ", dept : " + dept + ", salary :"
        + salary + " ]");
  }
}

// 使用示例
public class CompositePatternDemo {
  public static void main(String[] args) {
    // 使用 Employee 类来创建和打印员工的层次结构
    Employee CEO = new Employee("John", "CEO", 30000);

    Employee headSales = new Employee("Robert", "Head Sales", 20000);

    Employee headMarketing = new Employee("Michel", "Head Marketing", 20000);

    Employee clerk1 = new Employee("Laura", "Marketing", 10000);
    Employee clerk2 = new Employee("Bob", "Marketing", 10000);

    Employee salesExecutive1 = new Employee("Richard", "Sales", 10000);
    Employee salesExecutive2 = new Employee("Rob", "Sales", 10000);

    CEO.add(headSales);
    CEO.add(headMarketing);

    headSales.add(salesExecutive1);
    headSales.add(salesExecutive2);

    headMarketing.add(clerk1);
    headMarketing.add(clerk2);

    // 打印该组织的所有员工
    System.out.println(CEO);
    for (Employee headEmployee : CEO.getSubordinates()) {
      System.out.println(headEmployee);
      for (Employee employee : headEmployee.getSubordinates()) {
        System.out.println(employee);
      }
    }
  }
}
  • 执行程序,输出结果:
Employee :[ Name : John, dept : CEO, salary :30000 ]
Employee :[ Name : Robert, dept : Head Sales, salary :20000 ]
Employee :[ Name : Richard, dept : Sales, salary :10000 ]
Employee :[ Name : Rob, dept : Sales, salary :10000 ]
Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ]
Employee :[ Name : Laura, dept : Marketing, salary :10000 ]
Employee :[ Name : Bob, dept : Marketing, salary :10000 ]

5 总结

  • 组合模式通过将对象组合成树形结构,使得客户端可以一致地处理单个对象和组合对象。它适用于需要表示层次结构的对象以及统一处理单个对象和组合对象的场景。组合模式提高了系统的可扩展性和可维护性,但也可能增加系统的复杂性。在实际应用中,需要根据具体情况权衡使用组合模式的利弊。