文章目录
- [0. 个人感悟](#0. 个人感悟)
- [1. 概念](#1. 概念)
- [2. 适配场景](#2. 适配场景)
-
- [2.1 适合的场景](#2.1 适合的场景)
- [2.2 常见场景举例](#2.2 常见场景举例)
- [3. 实现方法](#3. 实现方法)
-
- [3.1 实现思路](#3.1 实现思路)
- [3.2 UML类图](#3.2 UML类图)
- [3.3 代码示例](#3.3 代码示例)
- [4. 优缺点](#4. 优缺点)
-
- [4.1 优点](#4.1 优点)
- [4.2 缺点](#4.2 缺点)
- [5. 源码分析](#5. 源码分析)
0. 个人感悟
- 责任链模式如其名,让接受者都有机会处理消息,链式调用
- 传统方式按流程来累代码,处理消息的代码会有很多的if-else判断由谁来处理,这样不仅职责不单一,而且需要了解处理者的实现逻辑,耦合太重;责任链模式可以让消息发送者和处理者解耦,发送者不需要知道谁来处理,各个处理者只需要做好自己的业务和消息传递就好
- 类似于现实中"踢皮球"或"层层审批"的流程
- 可以和模版方法模式配合,抽象一个基础handler,后面代码里有示例,有兴趣可以看看
1. 概念
英文定义 (《设计模式:可复用面向对象软件的基础》)
Avoid coupling the sender of request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
中文翻译
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
理解
- 解耦请求发送者和接收者,发送者不需要知道谁来处理请求
- 多个处理器对象组成一条链,请求沿着链传递
- 每个处理器决定是否处理请求,以及是否传递给下一个处理器
- 核心是处理器的"链式"组织和请求的"传递"机制
2. 适配场景
2.1 适合的场景
- 多级审批系统:请假、报销、采购等需要多级审批的业务流程
- 过滤器和拦截器:Web框架中的过滤器链、拦截器链
- 事件处理:GUI中的事件传递,如按钮点击事件冒泡
- 异常处理:不同级别的异常由不同的处理器处理
- 日志记录:不同级别的日志信息由不同的处理器记录
- 责任分离:将复杂的处理逻辑分解为多个小处理器
- 动态可配置的处理流程:处理流程可以运行时动态调整
2.2 常见场景举例
- 请假审批系统:员工提交请假申请 → 组长审批 → 经理审批 → HR备案
- Web请求处理:请求 → 字符编码过滤器 → 安全过滤器 → 日志过滤器 → 业务处理
- Java异常处理:try-catch-finally,异常沿着调用栈向上传递
- 日志系统:DEBUG → INFO → WARN → ERROR,不同级别的日志由不同处理器处理
- 游戏事件处理:鼠标点击事件 → UI系统 → 游戏对象系统 → 物理引擎
3. 实现方法
3.1 实现思路
-
定义抽象处理器接口/抽象类
- 声明处理请求的方法
- 定义设置后继处理器的方法
- 可选:定义处理请求的模板方法
-
实现具体处理器类
- 实现处理逻辑,判断是否能够处理当前请求
- 如果可以处理,则处理请求并终止传递
- 如果不能处理,则传递给后继处理器
-
构建处理链
- 创建处理器实例
- 按顺序链接处理器,形成处理链
- 可结合建造者模式简化链的构建
-
客户端使用
- 创建请求对象
- 将请求提交给处理链的第一个处理器
- 无需关心具体由哪个处理器处理
3.2 UML类图

角色说明
- Handler (抽象处理器):定义处理请求的接口,维护后继处理器引用
- ConcreteHandler (具体处理器):实现处理逻辑,处理可处理的请求,否则传递
- Client (客户端):创建处理链并提交请求
- Request (请求):封装请求信息和数据
3.3 代码示例
背景
以金额审批为例
- 角色包括经理、总监、CEO,对于不同金额有不同处理结果
- 实现上抽了一层
AbstractHandler,配合模版方法
处理器接口
java
public interface Handler {
/**
* @param request 请求
* @description 处理请求
* @author bigHao
* @date 2026/1/28
**/
void handleRequest(Request request);
/**
* @param next 下个处理器
* @description 设置下一个处理器
* @author bigHao
* @date 2026/1/28
**/
void setNext(Handler next);
}
处理器基础实现
java
public abstract class AbstractHandler implements Handler {
protected String name;
protected Handler nextHandler;
public AbstractHandler(String name) {
this.name = name;
}
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
System.out.println(STR."\{name} 可以处理 ");
process(request);
} else {
System.out.println(STR."\{name} 不可以处理 ");
nextHandler.handleRequest(request);
}
}
@Override
public void setNext(Handler next) {
this.nextHandler = next;
}
/**
* @param request 请求
* @return boolean 结果
* @description 是否可以处理
* @author bigHao
* @date 2026/1/28
**/
abstract boolean canHandle(Request request);
/**
* @param request 请求
* @description 执行请求
* @author bigHao
* @date 2026/1/28
**/
abstract void process(Request request);
}
处理器子类
java
public class ManagerHandler extends AbstractHandler {
public ManagerHandler(String name) {
super(name);
}
@Override
boolean canHandle(Request request) {
return request.getAmount() <= 1000;
}
@Override
void process(Request request) {
System.out.println("经理已经处理");
}
}
public class DirectorHandler extends AbstractHandler {
public DirectorHandler(String name) {
super(name);
}
@Override
boolean canHandle(Request request) {
return request.getAmount() <= 10000;
}
@Override
void process(Request request) {
System.out.println(name + "已经处理");
}
}
public class CEOHandler extends AbstractHandler {
public CEOHandler(String name) {
super(name);
}
@Override
boolean canHandle(Request request) {
return true;
}
@Override
void process(Request request) {
System.out.println(name + "已经处理");
}
}
辅助类
java
public class Request {
private int amount;
public Request(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
测试
java
public class Client {
static void main() {
// 设置调用链
Handler manager = new ManagerHandler("张经理");
Handler director = new DirectorHandler("李总监");
Handler ceo = new CEOHandler("王CEO");
manager.setNext(director);
director.setNext(ceo);
Request request = new Request(2000);
manager.handleRequest(request);
}
}
结果
张经理 不可以处理
李总监 可以处理
李总监已经处理
4. 优缺点
4.1 优点
高内聚低耦合
- 发送者与接收者解耦,发送者无需知道具体处理器
- 处理器之间松耦合,可以独立变化和复用
复用性与可维护性
- 处理器职责单一,易于复用
- 可以动态添加、删除或修改处理器顺序,扩展性好
- 符合开闭原则,新增处理器无需修改现有代码
灵活性与可读性
- 处理流程清晰可见,易于理解和调试
- 可以灵活组合处理器形成不同的处理链
4.2 缺点
性能与稳定性
- 链过长可能影响性能,请求需要遍历多个处理器
- 如果链配置不当,请求可能无法被处理(丢失请求)
- 调试较困难,需要跟踪请求在链中的传递过程
其他考虑
- 需要确保链中至少有一个处理器能处理请求,否则请求丢失
- 处理器之间的顺序依赖可能隐含业务逻辑,不易察觉
5. 源码分析
有兴趣可以了解下Spring MVC中的责任链模式,我计划后面专门整理Spring相关内容
参考: