一、前言

本篇主题为结构型模式中的第四个模式–组合模式。上篇 Java 设计模式主题为《Java 设计模式之装饰模式(八)》

二、简单介绍

# 2.1 定义

组合模式(Composite)是结构型的设计模式之一。通过递归手段来构造树形的对象结构以表示“部分-整体”的层次结构,并可以通过一个对象来访问整个对象树。

组合模式使得用户对单个对象和组合对象的使用具有一致性。

# 2.2 参与角色

  1. Component:为组合中的对象声明接口。在适当的情况下,实现所有类共有接口的缺省行为。

  2. Leaf:在组合中表示子部件,定义子部件对象的行为,该部件没有子部件。

  3. Composite:实现 Component 接口中与子部件有关的操作。

# 2.3 应用场景

  1. 需求中体现对象的部分-整体层次结构。

  2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

三、实现方式

我们以公司项目组的员工为例。

项目组由员工组成,员工角色分为项目负责人和开发人员。开发项目需要招聘开发人员,由项目负责人决定开发人员去留和管理手下,此时每个员工都是一个个体(部分)。当老板需要了解项目进度时,通常只需要让项目负责人(员工)汇报情况即可,这时员工可以看作一个整体。

抽象类(Component):可以看作公司发布的招聘岗位

  1. public abstract class Employee {
  2. protected List<Employee> employeeList;
  3. public abstract void add(Employee employee);
  4. public abstract void delete(Employee employee);
  5. public abstract void report();
  6. }

项目组/部门负责人(Composite):可以作为整体具备向老板汇报手下所有人的工作情况的义务。

  1. public class ProjectManager extends Employee {
  2. private String name;
  3. public ProjectManager(String name) {
  4. this.name = name;
  5. this.employeeList = new ArrayList<Employee>();
  6. }
  7. @Override
  8. public void add(Employee employee) {
  9. this.employeeList.add(employee);
  10. }
  11. @Override
  12. public void delete(Employee employee) {
  13. this.employeeList.remove(employee);
  14. }
  15. @Override
  16. public void report() {
  17. System.out.println(this.name + "汇报项目组员工的任务进度");
  18. for (Employee employee : employeeList) {
  19. employee.report();
  20. }
  21. }
  22. }

程序员(Leaf):项目组/部门的组成部分

  1. public class Programmer extends Employee {
  2. private String name;
  3. public Programmer(String name) {
  4. this.name = name;
  5. }
  6. @Override
  7. public void add(Employee employee) {
  8. }
  9. @Override
  10. public void delete(Employee employee) {
  11. }
  12. @Override
  13. public void report() {
  14. Random r = new Random();
  15. String temp = String.format("%.2f", r.nextFloat() * 100);
  16. System.out.println(this.name + "任务进度为" + temp + "%");
  17. }
  18. }

客户端:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Employee p1 = new Programmer("小白");
  4. Employee p2 = new Programmer("小黑");
  5. Employee projectManager = new ProjectManager("老阎");
  6. projectManager.add(p1);
  7. projectManager.add(p2);
  8. projectManager.report();
  9. }
  10. }

打印:

  1. 老阎汇报项目组员工的任务进度
  2. 小白任务进度为92.65%
  3. 小黑任务进度为43.30%

UML 类图表示如下: