责任链模式是一种行为型设计模式,其核心思想是将多个 “处理器”(负责处理特定请求的对象)串联成一条 “链”,当请求产生时,请求会沿着这条链依次传递,直到某个处理器能够处理该请求并返回结果,或请求到达链的末端仍未被处理(可选择默认处理或忽略)。

该模式的本质是解耦 “请求的发送者” 和 “请求的处理者”—— 发送者无需知道哪个处理器会处理请求,只需将请求传递给链的第一个节点即可;同时,处理器也无需知道链的整体结构,只需关注自身负责的请求类型,以及无法处理时将请求传递给下一个节点。

责任链模式的UML如下:

image.png

责任链模式通常包含以下 3 个核心角色,各角色职责明确,共同构成请求处理的链式结构:

角色名称(英文) 核心职责 典型实现
抽象处理器(Handler) 定义处理请求的接口,声明一个 “下一个处理器” 的引用,提供设置下一个节点的方法 声明 handleRequest(request)(处理请求的核心方法)、setNextHandler(handler)(设置下一个处理器)
具体处理器(Concrete Handler) 实现抽象处理器接口,判断自身是否能处理当前请求:

1. 能处理则直接处理并返回结果;

2. 不能处理则调用 “下一个处理器” 的 handleRequest 方法传递请求
重写 handleRequest 方法,添加请求类型判断逻辑(如 “金额是否在自身处理范围内”“请求类型是否匹配”)
请求者(Client) 创建请求对象,将请求传递给责任链的第一个处理器,无需关注后续处理流程 实例化具体处理器并构建链式结构,调用链首处理器的 handleRequest 方法发送请求

我们用一个费用审批流程为例,通过Java代码说明责任链模式。

首先定义一个责任链的结构抽象,这里是Handler抽象类,它包含一个执行nexHandler的引用和处理请求的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 抽象处理器类
public abstract class Handler {
// 下一个处理器
protected Handler nextHandler;

// 设置下一个处理器
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}

// 处理请求的抽象方法
public abstract String handleRequest(Request request);
}

然后我们封装具体的请求信息,其中包括了请求金额和事由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 请求类(封装审批请求信息)
public class Request {
// 审批金额
private double amount;
// 审批事由
private String reason;

public Request(double amount, String reason) {
this.amount = amount;
this.reason = reason;
}

public double getAmount() {
return amount;
}

public String getReason() {
return reason;
}
}

在我们的场景中,我们定义了三个处理审批请求的具体类

  • TeamLeaderHandler:处理 1000 元及以下的审批
  • ManagerHandler:处理 1001-5000 元的审批
  • DirectorHandler:处理 5000 元以上的审批
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 组长处理器(处理1000元以下的审批)
public class TeamLeaderHandler extends Handler {
@Override
public String handleRequest(Request request) {
// 如果金额小于等于1000元,组长可以审批
if (request.getAmount() <= 1000) {
return "组长审批通过:" + request.getReason() + ",金额:" + request.getAmount() + "元";
} else {
// 否则传递给下一个处理器
if (nextHandler != null) {
return nextHandler.handleRequest(request);
}
}
return "审批流程结束,无人处理该请求";
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 经理处理器(处理1001-5000元的审批)
public class ManagerHandler extends Handler {
@Override
public String handleRequest(Request request) {
// 如果金额在1001-5000元之间,经理可以审批
if (request.getAmount() > 1000 && request.getAmount() <= 5000) {
return "经理审批通过:" + request.getReason() + ",金额:" + request.getAmount() + "元";
} else {
// 否则传递给下一个处理器
if (nextHandler != null) {
return nextHandler.handleRequest(request);
}
}
return "审批流程结束,无人处理该请求";
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 总监处理器(处理5001元以上的审批)
public class DirectorHandler extends Handler {
@Override
public String handleRequest(Request request) {
// 如果金额大于5000元,总监可以审批
if (request.getAmount() > 5000) {
return "总监审批通过:" + request.getReason() + ",金额:" + request.getAmount() + "元";
} else {
// 否则传递给下一个处理器
if (nextHandler != null) {
return nextHandler.handleRequest(request);
}
}
return "审批流程结束,无人处理该请求";
}
}

客户端的调用示例如下:

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
28
29
30
31
32
33
// 客户端类
public class Client {
// 创建责任链
public static Handler createChain() {
// 创建各个处理器
Handler teamLeader = new TeamLeaderHandler();
Handler manager = new ManagerHandler();
Handler director = new DirectorHandler();

// 构建责任链:组长 -> 经理 -> 总监
teamLeader.setNextHandler(manager);
manager.setNextHandler(director);

// 返回链头
return teamLeader;
}

public static void main(String[] args) {
// 创建责任链
Handler chain = createChain();

// 创建不同的请求
Request request1 = new Request(800, "购买办公用品");
Request request2 = new Request(3000, "团队建设活动");
Request request3 = new Request(8000, "购买新设备");

// 处理请求
System.out.println(chain.handleRequest(request1));
System.out.println(chain.handleRequest(request2));
System.out.println(chain.handleRequest(request3));
}
}

责任链的处理流程如下:

  1. 客户端创建责任链,设置处理器之间的先后关系
  2. 客户端创建请求对象,并将其提交给责任链的第一个处理器
  3. 请求在责任链中传递:
    • 如果当前处理器可以处理请求,则直接处理并返回结果
    • 如果当前处理器不能处理请求,则将请求传递给下一个处理器
    • 直到请求被处理或到达链的末端

这种设计模式的优势在于:

  • 降低了请求发送者和接收者之间的耦合
  • 可以灵活地增加或修改处理逻辑
  • 符合开闭原则,便于扩展新的处理器
  • 避免了多重条件判断的复杂代码结构