当前位置: 首页 > news >正文

设计模式(十四)行为型:职责链模式详解

设计模式(十四)行为型:职责链模式详解

职责链模式(Chain of Responsibility Pattern)是 GoF 23 种设计模式中的行为型模式之一,其核心价值在于将多个处理对象(处理器)连接成一条链,使请求沿着链传递,直到被某个处理器处理为止。它解耦了请求的发送者与接收者,允许动态地组织处理流程,提升系统的灵活性与可扩展性。职责链模式是实现“开闭原则”的典范,广泛应用于审批流程(请假、报销)、事件处理(GUI 事件分发)、日志系统(多级日志处理器)、中间件管道(如 Web 框架的过滤器链)、异常处理、权限校验等需要多级判断或顺序处理的场景,是构建可配置、可插拔业务流程的关键架构模式。

一、详细介绍

职责链模式解决的是“一个请求可能由多个对象处理,但具体由谁处理在运行时决定”的问题。在传统设计中,客户端需要显式判断由哪个对象处理请求,导致代码中充斥条件判断(if-else 或 switch),难以维护和扩展。当处理逻辑变更或新增处理器时,客户端代码必须修改。

职责链模式通过将多个处理器组织成一条链,客户端只需将请求发送给链的首节点,后续传递由处理器自行决定。每个处理器都持有对下一个处理器的引用(或通过外部容器管理),并在处理请求时:

  1. 判断自己是否能处理该请求;
  2. 若能处理,则执行业务逻辑并结束;
  3. 若不能处理,则将请求转发给链中的下一个处理器;
  4. 若链尾仍未处理,则可选择丢弃或抛出异常。

该模式包含以下核心角色:

  • Handler(抽象处理器):定义处理请求的接口,通常包含一个方法(如 handleRequest())和一个指向后继处理器的引用(successor)。可以是抽象类或接口。
  • ConcreteHandler(具体处理器):实现 Handler 接口,包含具体的处理逻辑。它决定是否处理当前请求,若不处理则将请求转发给后继。
  • Client(客户端):创建处理器链,并向链的首节点发送请求。客户端不关心具体由哪个处理器处理,也不依赖具体处理器类型。

职责链的组织方式有两种:

  1. 显式链(Explicit Chain):每个处理器持有对下一个处理器的引用,形成链式结构。
  2. 中心化链(Centralized Chain):由一个容器(如 Chain 类)管理处理器列表,按顺序调用。

职责链模式的关键优势:

  • 解耦请求发送者与接收者:客户端无需知道具体处理者。
  • 增强系统灵活性:可动态添加、删除或重排处理器。
  • 符合开闭原则:新增处理器无需修改现有代码。
  • 支持多种处理逻辑:可实现“首个匹配即处理”或“全部处理”等策略。

与“状态模式”相比,职责链关注请求的传递与处理,状态模式关注对象行为随状态改变;与“观察者模式”相比,职责链是单向链式传递,观察者是广播式通知;与“策略模式”相比,职责链允许多个策略顺序参与,策略模式是单一策略选择

二、职责链模式的UML表示

以下是职责链模式的标准 UML 类图:

implements
implements
implements
successor
sends request
«abstract»
Handler
-successor: Handler
+setSuccessor(successor: Handler)
+handleRequest(request: Request)
ConcreteHandlerA
+handleRequest(request: Request)
ConcreteHandlerB
+handleRequest(request: Request)
ConcreteHandlerC
+handleRequest(request: Request)
Client
+main(args: String[])

图解说明

  • Handler 定义处理接口和后继引用。
  • ConcreteHandlerA/B/C 实现具体处理逻辑,可选择处理请求或转发。
  • 处理器通过 setSuccessor() 构成链。
  • 客户端向链首发送请求,请求沿链传递。

三、一个简单的Java程序实例及其UML图

以下是一个公司请假审批系统的示例,展示不同级别的管理者对不同天数的请假请求进行审批。

Java 程序实例
// 请求类
class LeaveRequest {private String employee;private int days;private String reason;public LeaveRequest(String employee, int days, String reason) {this.employee = employee;this.days = days;this.reason = reason;}// Getter 方法public String getEmployee() { return employee; }public int getDays() { return days; }public String getReason() { return reason; }@Overridepublic String toString() {return "LeaveRequest{" +"employee='" + employee + '\'' +", days=" + days +", reason='" + reason + '\'' +'}';}
}// 抽象处理器:审批者
abstract class Approver {protected Approver successor;protected String name;protected String position;public Approver(String name, String position) {this.name = name;this.position = position;}public void setSuccessor(Approver successor) {this.successor = successor;}// 处理请求的抽象方法public abstract void handleRequest(LeaveRequest request);
}// 具体处理器:组长(可批1-3天)
class TeamLeader extends Approver {public TeamLeader(String name) {super(name, "Team Leader");}@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 3) {System.out.println("✅ [" + position + " " + name + "] 批准了 " + request.getEmployee() +" 的 " + request.getDays() + " 天请假申请。");} else if (successor != null) {System.out.println("⏭️  [" + position + " " + name + "] 无法处理,转交上级...");successor.handleRequest(request);}}
}// 具体处理器:部门经理(可批4-7天)
class DepartmentManager extends Approver {public DepartmentManager(String name) {super(name, "Department Manager");}@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 7) {System.out.println("✅ [" + position + " " + name + "] 批准了 " + request.getEmployee() +" 的 " + request.getDays() + " 天请假申请。");} else if (successor != null) {System.out.println("⏭️  [" + position + " " + name + "] 无法处理,转交上级...");successor.handleRequest(request);}}
}// 具体处理器:总经理(可批任意天数)
class GeneralManager extends Approver {public GeneralManager(String name) {super(name, "General Manager");}@Overridepublic void handleRequest(LeaveRequest request) {System.out.println("✅ [" + position + " " + name + "] 特批了 " + request.getEmployee() +" 的 " + request.getDays() + " 天请假申请。");}
}// 客户端使用示例
public class ChainOfResponsibilityDemo {public static void main(String[] args) {System.out.println("🏢 公司请假审批系统 - 职责链模式示例\n");// 创建处理器链Approver teamLeader = new TeamLeader("张组长");Approver deptManager = new DepartmentManager("李经理");Approver gm = new GeneralManager("王总");// 构建链:组长 -> 部门经理 -> 总经理teamLeader.setSuccessor(deptManager);deptManager.setSuccessor(gm);// 模拟不同请假请求LeaveRequest req1 = new LeaveRequest("小明", 2, "感冒");LeaveRequest req2 = new LeaveRequest("小红", 5, "家庭事务");LeaveRequest req3 = new LeaveRequest("小刚", 10, "出国旅游");System.out.println("📝 处理请假请求:");teamLeader.handleRequest(req1);System.out.println("---");teamLeader.handleRequest(req2);System.out.println("---");teamLeader.handleRequest(req3);System.out.println("\n💡 说明:请求沿链传递,直到被合适处理器处理。");System.out.println("🔧 可动态调整链结构,如新增总监层。");}
}
实例对应的UML图(简化版)
extends
extends
extends
successor
sends request
creates
LeaveRequest
-employee: String
-days: int
-reason: String
+getEmployee()
+getDays()
+getReason()
«abstract»
Approver
-successor: Approver
-name: String
-position: String
+setSuccessor(successor: Approver)
+handleRequest(request: LeaveRequest)
TeamLeader
+handleRequest(request: LeaveRequest)
DepartmentManager
+handleRequest(request: LeaveRequest)
GeneralManager
+handleRequest(request: LeaveRequest)
Client
+main(args: String[])

运行说明

  • Approver 定义了处理链的结构和接口。
  • TeamLeaderDepartmentManagerGeneralManager 实现具体审批逻辑。
  • 请求从 teamLeader 开始,根据天数逐级传递。
  • 客户端只需将请求交给链首,无需关心处理细节。

四、总结

特性说明
核心目的解耦请求发送者与接收者,实现请求的动态处理
实现机制构建处理器链,请求沿链传递直至被处理
优点降低耦合、增强灵活性、支持动态配置、符合开闭原则
缺点请求可能未被处理(需设计默认处理)、性能可能下降(链过长)、调试困难
适用场景审批流程、事件处理、日志分级、过滤器链、异常处理、权限校验
不适用场景处理逻辑简单、必须由特定对象处理、性能敏感且链过长

职责链模式使用建议

  • 应确保链中有至少一个处理器能处理请求,避免“黑洞”。
  • 可引入“默认处理器”处理未匹配请求。
  • 支持运行时动态构建和修改链结构。
  • 在 Java 中,Servlet 的 FilterChain、Spring 的拦截器链是典型应用。

架构师洞见:
职责链模式是“流程可配置化”与“关注点分离”的高级体现。在现代架构中,其思想已演变为中间件管道事件驱动架构工作流引擎的核心。例如,在 Web 框架(如 Express、Koa)中,中间件链按顺序处理 HTTP 请求;在微服务中,API 网关的过滤器链执行认证、限流、日志等操作;在工作流引擎(如 Activiti)中,任务节点构成处理链;在前端框架中,事件冒泡机制本质是职责链。

未来趋势是:职责链将与低代码流程引擎深度融合,通过可视化拖拽构建处理链;在AI Agent 系统中,Agent 的“决策链”(Reasoning Chain)可视为职责链,每个步骤由不同工具或模型处理;在可观测性系统中,日志、指标、追踪数据将通过职责链进行分级处理与路由。

掌握职责链模式,有助于设计出灵活、可配置、易扩展的业务流程。作为架构师,应在涉及“多级判断”、“顺序处理”或“流程编排”的场景中主动引入职责链。职责链不仅是模式,更是流程治理的哲学——它提醒我们:真正的灵活性,来自于将“决策路径”从硬编码中解放出来,交由配置与链式逻辑动态决定。

http://www.dtcms.com/a/300932.html

相关文章:

  • add新增管理员功能、BaseController类的简介--------示例OJ
  • linux安装nvm教程
  • Windows 11修复损坏的 ISO 文件
  • 二、搭建springCloudAlibaba2021.1版本分布式微服务-Nacos搭建及服务注册和配置中心
  • RHEL9 网络配置入门:IP 显示、主机名修改与配置文件解析
  • 【C++】红黑树实现
  • logstash采集springboot微服务日志
  • 使用Python,OpenCV,K-Means聚类查找图像中最主要的颜色
  • C语言:函数
  • AI大模型前沿:Muyan-TTS开源零样本语音合成技术解析
  • 力扣129. 求根节点到叶节点数字之和
  • Python day26
  • 基于 KNN 算法的手写数字识别项目实践
  • OpenLayers 综合案例-点位聚合
  • Java Ai(day04)
  • Android CameraX 使用指南:简化相机开发
  • 7.25 C/C++蓝桥杯 |排序算法【下】
  • git删除远程分支和本地分支
  • Windows10+WSL2+Docker相关整理
  • IP--MGER综合实验报告
  • git 修改 更新
  • Red靶机攻略
  • 洛谷P2880 [USACO07JAN] Balanced Lineup G
  • Java面试新趋势:云原生与新兴框架实战解析
  • 计算机网络:(十二)传输层(上)运输层协议概述
  • Docmost:一款开源的Wiki和文档协作软件
  • 【Linux | 网络】传输层(UDP和TCP)
  • 电动汽车转向系统及其工作原理
  • 深入理解Linux网络-读书笔记(一)
  • 新手开发 App,容易陷入哪些误区?