一、前言

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

二、简单介绍

2.1 定义

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

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

2.2 参与角色

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

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

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

2.3 应用场景

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

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

三、实现方式

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

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

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

1
2
3
4
5
6
7
8
9
10
public abstract class Employee {

protected List<Employee> employeeList;

public abstract void add(Employee employee);

public abstract void delete(Employee employee);

public abstract void report();
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class ProjectManager extends Employee {

private String name;

public ProjectManager(String name) {
this.name = name;
this.employeeList = new ArrayList<Employee>();
}

@Override
public void add(Employee employee) {
this.employeeList.add(employee);
}

@Override
public void delete(Employee employee) {
this.employeeList.remove(employee);
}

@Override
public void report() {
System.out.println(this.name + "汇报项目组员工的任务进度");
for (Employee employee : employeeList) {
employee.report();
}
}
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Programmer extends Employee {

private String name;

public Programmer(String name) {
this.name = name;
}

@Override
public void add(Employee employee) {

}

@Override
public void delete(Employee employee) {

}

@Override
public void report() {
Random r = new Random();
String temp = String.format("%.2f", r.nextFloat() * 100);
System.out.println(this.name + "任务进度为" + temp + "%");
}

}

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client {

public static void main(String[] args) {

Employee p1 = new Programmer("小白");
Employee p2 = new Programmer("小黑");

Employee projectManager = new ProjectManager("老阎");
projectManager.add(p1);
projectManager.add(p2);

projectManager.report();
}
}

打印:

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

UML 类图表示如下: