23种设计模式之【责任链模式】-核心原理与 Java 实践
文章目录
- Java 责任链模式详解
- 核心角色:
- 优点:
- Java 责任链模式示例
- 代码解析
- 经典应用场景
Java 责任链模式详解
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过构建一个处理者对象链,使请求能够在链中传递,直到有一个处理者能够处理该请求为止。
核心角色:
抽象处理者(Handler):定义处理请求的接口,包含一个指向下一个处理者的引用
具体处理者(ConcreteHandler):实现处理请求的方法,判断能否处理当前请求,如果可以则处理,否则将请求传递给下一个处理者
请求(Request):包含需要处理的信息
优点:
降低请求发送者和接收者之间的耦合度
可以动态调整责任链结构
符合开闭原则,新增处理者无需修改原有代码
Java 责任链模式示例
下面以员工报销审批流程为例实现责任链模式:
组长可审批 ≤1000 元的报销
部门经理可审批 ≤5000 元的报销
总经理可审批 ≤10000 元的报销
public class TestZenRenLian {public static void main(String[] args) {// 创建各个审批者Approver teamLeader = new TeamLeader("张三");Approver deptManager = new DepartmentManager("李四");Approver generalManager = new GeneralManager("王五");// 构建责任链:组长→部门经理→总经理teamLeader.setNextApprover(deptManager);deptManager.setNextApprover(generalManager);// 创建报销请求Reimbursement request1 = new Reimbursement("员工A", 800);Reimbursement request2 = new Reimbursement("员工B", 3000);Reimbursement request3 = new Reimbursement("员工C", 8000);Reimbursement request4 = new Reimbursement("员工D", 15000); // 超过最大审批权限// 处理请求teamLeader.processReimbursement(request1);teamLeader.processReimbursement(request2);teamLeader.processReimbursement(request3);teamLeader.processReimbursement(request4);}// 报销请求类public static class Reimbursement {private String name; // 申请人private double amount; // 报销金额public Reimbursement(String name, double amount) {this.name = name;this.amount = amount;}public String getName() {return name;}public double getAmount() {return amount;}}// 抽象处理者类public abstract static class Approver {protected Approver nextApprover; // 下一个审批人protected String name; // 审批人姓名public Approver(String name) {this.name = name;}// 设置下一个审批人public void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}// 处理报销请求的抽象方法public abstract void processReimbursement(Reimbursement request);}// 组长(处理≤1000元的报销)public static class TeamLeader extends Approver {public TeamLeader(String name) {super(name);}@Overridepublic void processReimbursement(Reimbursement request) {if (request.getAmount() <= 1000) {System.out.println("组长 " + name + " 批准了 " + request.getName() +" 的 " + request.getAmount() + " 元报销");} else if (nextApprover != null) {// 超过权限,传递给下一个审批人nextApprover.processReimbursement(request);} else {System.out.println(request.getName() + " 的 " + request.getAmount() + " 元报销无人能审批");}}}// 部门经理(处理≤5000元的报销)public static class DepartmentManager extends Approver {public DepartmentManager(String name) {super(name);}@Overridepublic void processReimbursement(Reimbursement request) {if (request.getAmount() <= 5000) {System.out.println("部门经理 " + name + " 批准了 " + request.getName() +" 的 " + request.getAmount() + " 元报销");} else if (nextApprover != null) {nextApprover.processReimbursement(request);} else {System.out.println(request.getName() + " 的 " + request.getAmount() + " 元报销无人能审批");}}}// 总经理(处理≤10000元的报销)public static class GeneralManager extends Approver {public GeneralManager(String name) {super(name);}@Overridepublic void processReimbursement(Reimbursement request) {if (request.getAmount() <= 10000) {System.out.println("总经理 " + name + " 批准了 " + request.getName() +" 的 " + request.getAmount() + " 元报销");} else if (nextApprover != null) {nextApprover.processReimbursement(request);} else {System.out.println(request.getName() + " 的 " + request.getAmount() + " 元报销无人能审批");}}}}
//组长 张三 批准了 员工A 的 800.0 元报销
//部门经理 李四 批准了 员工B 的 3000.0 元报销
//总经理 王五 批准了 员工C 的 8000.0 元报销
//员工D 的 15000.0 元报销无人能审批
代码解析
- Reimbursemen请求信息类:封装了报销请求的信息,包括申请人姓名和报销金额
- Approver 抽象类:
定义了所有审批者的共同行为
包含一个 nextApprover 引用,用于指向下一个审批者
提供了设置下一个审批者的方法 setNextApprover()
声明了处理报销请求的抽象方法 processReimbursement() - 具体处理者:
每个处理者只处理自己权限范围内的请求
若无法处理,则将请求传递给下一个处理者
形成了 “组长→部门经理→总经理” 的处理链
经典应用场景
责任链模式在实际开发中有许多经典应用场景,其核心是「将请求的发送者与处理者解耦,让多个处理者有机会依次处理请求」。以下是一些常见的应用场景:
- 审批流程场景
这是责任链模式最典型的应用,如:
请假审批:员工请假 → 小组长审批(≤3 天)→ 部门经理审批(≤7 天)→ 总经理审批(≤30 天)
报销审批:金额从小到大,依次由组长、部门经理、财务总监等逐级审批
公文流转:文件按级别依次经过不同部门或职位处理
特点:每个处理者有明确的权限范围,超出则传递给下一级。 - 过滤器 / 拦截器场景
在 Web 开发中,过滤器(Filter)或拦截器(Interceptor)链是责任链模式的经典实现:
Servlet Filter:请求到达目标资源前,会经过多个过滤器(如编码过滤、登录验证、权限检查、XSS 过滤等),每个过滤器可决定是否继续传递请求
Spring Interceptor:对 Controller 方法的调用进行拦截,可依次执行预处理、后处理等操作
日志过滤:不同级别(Debug、Info、Warn、Error)的日志处理器依次判断是否需要记录日志
特点:每个处理者专注于单一职责(如验证、过滤、转换),可动态组合顺序。 - 事件传递场景
在 GUI 或事件驱动开发中,事件会沿着组件层级传递:
GUI 组件事件:如按钮点击事件,会先由按钮自身处理,若未处理则传递给父容器(面板→窗口→应用程序)
Android 事件分发:触摸事件从 View 到 ViewGroup 再到 Activity 的传递链,每个层级可决定是否消费事件或继续传递
特点:事件沿层级链传递,上层组件可覆盖下层处理逻辑。 - 异常处理场景
在异常处理中,不同的异常处理器可形成责任链:
异常捕获链:代码中多个catch块实际上构成了责任链,从具体异常到通用异常依次匹配(如先捕获NullPointerException,再捕获Exception)
自定义异常处理器:系统中注册多个异常处理器,依次尝试处理异常,直到被处理或抛出
特点:按异常类型的范围从小到大依次处理。 - 请求处理管道(Pipeline)
在框架或中间件中,请求处理常设计为管道模式(本质是责任链的变种):
Netty 的 ChannelPipeline:网络请求在 Handler 链中依次经过编码、解码、业务处理等步骤
ASP.NET Core 中间件:HTTP 请求通过一系列中间件(如路由、认证、静态文件处理)组成的管道,每个中间件可决定是否将请求传递给下一个
特点:处理流程呈流水线式,每个节点专注于特定处理步骤。
责任链模式的核心优势
解耦:请求发送者无需知道具体由哪个处理者处理,只需交给链的入口
灵活性:可动态增删处理者或调整链的顺序,符合开闭原则
单一职责:每个处理者只关注自己职责范围内的逻辑
当需要「多个对象处理同一类请求,且处理者的选择需要动态决定」时,责任链模式是最佳选择之一。