职责链模式
引言
在软件系统中,当请求需要多级审批(如报销流程)或动态路由(如HTTP中间件)时,硬编码处理逻辑会导致代码臃肿和可扩展性差。职责链模式通过将处理对象连成链条,实现请求的自动化传递与按需处理,成为解耦请求与处理的经典解决方案。
诞生背景
GoF在《设计模式》中提出职责链模式,解决三大痛点:
- 处理逻辑僵化:新增处理步骤需修改核心代码(如风控系统增加新规则)
- 请求发送者臃肿:客户端需显式调用所有处理器(如订单状态机调用10+校验器)
- 动态路由缺失:无法运行时调整处理流程(如日志过滤链动态开关)
演进过程
- GoF基础(1994):确立处理器链与传递机制
- Web框架演进:HTTP中间件链(Express.js的
next(),Spring Interceptor) - 现代应用:微服务网关的过滤器链(Spring Cloud Gateway)
核心概念
- 抽象处理器(Handler):定义处理接口与后继链设置方法
- 具体处理器(Concrete Handler):实现请求处理逻辑与传递机制
- 客户端(Client):初始化处理链并提交请求
通用实现
Java 实现
java
// 抽象处理器
abstract class Handler {
protected Handler next;
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(int request);
}
// 具体处理器:级别1
class ConcreteHandler1 extends Handler {
public void handleRequest(int request) {
if (request <= 10) {
System.out.println("Handler1 processed: " + request);
} else if (next != null) {
next.handleRequest(request); // 传递请求
}
}
}
// 具体处理器:级别2
class ConcreteHandler2 extends Handler {
public void handleRequest(int request) {
if (request <= 20) {
System.out.println("Handler2 processed: " + request);
} else if (next != null) {
next.handleRequest(request);
}
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Handler chain = new ConcreteHandler1();
chain.setNext(new ConcreteHandler2());
chain.handleRequest(5); // Handler1处理
chain.handleRequest(15); // Handler2处理
}
}PHP 实现
php
// 抽象处理器
abstract class Handler {
protected ?Handler $next = null;
public function setNext(Handler $next): void {
$this->next = $next;
}
abstract public function handleRequest(int $request): void;
}
// 具体处理器:日志过滤器
class LogFilter extends Handler {
public function handleRequest(int $request): void {
if ($request > 100) {
echo "LogFilter: Request too large\n";
} else if ($this->next) {
$this->next->handleRequest($request);
}
}
}
// 具体处理器:权限校验
class AuthHandler extends Handler {
public function handleRequest(int $request): void {
if ($request < 0) {
echo "AuthHandler: Invalid request\n";
} else if ($this->next) {
$this->next->handleRequest($request);
}
}
}
// 客户端
$chain = new LogFilter();
$chain->setNext(new AuthHandler());
$chain->handleRequest(50); // 通过所有处理器
$chain->handleRequest(150); // LogFilter拦截应用场景
- 多级审批系统:报销流程(员工→经理→财务)
- 请求过滤链:Web中间件(鉴权→日志→缓存)
- 异常处理:错误捕获链(业务异常→系统异常→全局兜底)
- 游戏事件处理:伤害计算链(防御减免→暴击判定)
案例:订单风控系统
Java 实现
java
// 风控处理器基类
abstract class RiskHandler {
protected RiskHandler next;
public void setNext(RiskHandler next) { this.next = next; }
public abstract void check(Order order);
}
// 具体处理器:黑名单校验
class BlacklistHandler extends RiskHandler {
public void check(Order order) {
if (order.user.isBlacklisted()) {
System.out.println("BLOCKED: User in blacklist");
} else if (next != null) {
next.check(order); // 传递订单
}
}
}
// 具体处理器:金额校验
class AmountHandler extends RiskHandler {
public void check(Order order) {
if (order.amount > 10000) {
System.out.println("ALERT: Large amount order");
} else if (next != null) {
next.check(order);
}
}
}
// 客户端使用
RiskHandler chain = new BlacklistHandler();
chain.setNext(new AmountHandler());
chain.check(order); // 自动触发风控链PHP 实现
php
// 抽象日志处理器
abstract class LogHandler {
protected ?LogHandler $next = null;
public function setNext(LogHandler $next): void {
$this->next = $next;
}
abstract public function process(string $log): void;
}
// 具体处理器:错误日志
class ErrorHandler extends LogHandler {
public function process(string $log): void {
if (str_contains($log, "ERROR")) {
echo "Error logged to file\n";
} else if ($this->next) {
$this->next->process($log);
}
}
}
// 具体处理器:调试日志
class DebugHandler extends LogHandler {
public function process(string $log): void {
if (str_contains($log, "DEBUG")) {
echo "Debug info sent to console\n";
} else if ($this->next) {
$this->next->process($log);
}
}
}
// 客户端
$chain = new ErrorHandler();
$chain->setNext(new DebugHandler());
$chain->process("DEBUG: User logged in"); // 触发DebugHandler优点
- 动态解耦:新增处理器无需修改客户端
- 灵活扩展:运行时动态调整处理链顺序
- 单一职责:每个处理器专注独立逻辑
- 请求路由:自动选择匹配的处理者
缺点
- 性能风险:长链导致请求传递开销
- 调试困难:请求在链中“隐身”传递
- 循环依赖:链配置错误引发死循环
- 处理不确定性:请求可能未被任何处理器消费
扩展
- 中断机制:处理器可中断传递(如Spring MVC拦截器返回
false) - 双向链条:支持请求反向传递(如异常处理链)
- 链工厂模式:封装复杂链的构建过程
- 异步职责链:处理器异步消费请求(如Akka Actor模型)
模式协作
- 与组合模式:构建树形处理链(如XML解析器)
- 与命令模式:将请求封装为可传递对象
- 与装饰器模式:动态增强处理器能力
- 与观察者模式:实现事件广播链(如Spring事件机制)
延伸思考
- 微服务治理:API网关路由链(鉴权→限流→熔断)
- 前端应用:表单校验链(必填项→格式校验→异步验证)
- 性能优化:
- 短路处理(如校验失败立即终止)
- 并行执行链(如ForkJoinPool拆分任务)
- 反模式警示:避免构建“神链”(超过10个处理器的超长链)
总结
职责链模式是动态路由的编织者,通过解耦请求发送与处理逻辑,实现“流水线式”的请求处理。其核心价值在于:灵活可扩展的流程编排与优雅的责任分离。在中间件系统、审批工作流等场景中,职责链模式能显著提升系统可维护性,成为行为设计模式中的“流程引擎”。