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

设计模式9-责任链模式

定义

        Chain of Responsibility Pattern:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链, 并沿着这条链传递该请求,直到有对象处理它为止。

优势

  • 解耦请求发送者与接收者,发送者无需知道具体由哪个对象处理请求;

  • 新增处理者时只需加入链条,无需修改原有代码,符合 “开闭原则”。

场景

生活场景

最典型的例子是 公司请假审批流程:

  • 请假 1 天以内:组长直接审批;

  • 请假 1-3 天:组长无权处理,传递给部门经理审批;

  • 请假 3 天以上:部门经理无权处理,传递给总经理审批。

这里,组长→部门经理→总经理形成一条 “责任链”,请假请求会沿着链条传递,直到被对应的负责人处理。

Java 中的责任链场景

  1. Servlet Filter 链:
    客户端请求经过多个 Filter(过滤器)处理(如编码过滤、权限校验、日志记录等),每个 Filter 可选择处理请求后传递给下一个 Filter,或直接终止请求。

  2. Spring Interceptor 链:
    Spring MVC 中的拦截器链,对请求进行预处理(如登录验证)、后处理(如数据封装),每个 Interceptor 可决定是否继续传递请求。

  3. 异常处理机制:
    Java 的异常捕获(try-catch)本质上也是责任链:异常会从发生处向上传递,直到被第一个匹配的 catch 块处理。

代码

// 抽象审批者类:定义责任链节点的通用行为
abstract class Approver {protected Approver nextApprover; // 下一个审批者(责任链的下一个节点)// 设置下一个审批者public void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}// 抽象处理方法:子类需实现具体审批逻辑public abstract void handleRequest(LeaveRequest request);
}// 请假请求类:封装请求信息class LeaveRequest {private String name; // 申请人姓名private int days; // 请假天数public LeaveRequest(String name, int days) {this.name = name;this.days = days;}// getter方法public String getName() {return name;}public int getDays() {return days;}
}// 组长:处理1天以内的请假class GroupLeader extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() <= 1) {System.out.println("组长批准 " + request.getName() + " 请假" + request.getDays() + "天");} else {// 超过权限,传递给下一个审批者if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 总经理:处理3天以上的请假
class GeneralManager extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() > 3) {System.out.println("总经理批准 " + request.getName() + " 请假" + request.getDays() + "天");} else {// 超过权限,传递给下一个审批者(此处为链的终点,可省略)if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 部门经理:处理1-3天的请假class DeptManager extends Approver {@Overridepublic void handleRequest(LeaveRequest request) {if (request.getDays() > 1 && request.getDays() <= 3) {System.out.println("部门经理批准 " + request.getName() + " 请假" + request.getDays() + "天");} else {// 超过权限,传递给下一个审批者if (nextApprover != null) {nextApprover.handleRequest(request);}}}
}// 测试类:构建责任链并模拟请假请求
class Client {public static void main(String[] args) {// 创建审批者Approver groupLeader = new GroupLeader();Approver deptManager = new DeptManager();Approver generalManager = new GeneralManager();// 构建责任链:组长→部门经理→总经理groupLeader.setNextApprover(deptManager);deptManager.setNextApprover(generalManager);// 模拟请假请求LeaveRequest request1 = new LeaveRequest("张三", 1); // 1天:组长处理LeaveRequest request2 = new LeaveRequest("李四", 2); // 2天:部门经理处理LeaveRequest request3 = new LeaveRequest("王五", 5); // 5天:总经理处理// 发送请求(从链的起点开始)groupLeader.handleRequest(request1);groupLeader.handleRequest(request2);groupLeader.handleRequest(request3);}
}

责任链模式代码

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

相关文章:

  • UDC否定响应码学习
  • 未成功:使用 Nginx 搭建代理服务器(正向代理 HTTPS 网站)
  • 《StarRocks、Doris、ClickHouse 深度对比:三大 OLAP 引擎的优劣与应用场景》
  • go的实现arp客户端
  • 《方法论》--笛卡尔
  • 【学习笔记】非异步安全函数(禁止在信号处理中调用)
  • 雷卯针对香橙派Orange Pi 4开发板防雷防静电方案
  • 【Golang】 项目启动方法
  • Android12 user版本默认开启adb调试
  • centos7安装java mysql redis nginx
  • docker 所有常用命令,配上思维导图,加图表显示
  • 713 乘积小于k的子数组
  • Mysql数据挂载
  • Leetcode+Java+动态规划IV
  • electron离线开发环境变量ELECTRON_OVERRIDE_DIST_PATH
  • [MT6835] MT6835开启secureboot导致写入分区提示Security deny for [customer].
  • 【图像算法 - 25】基于深度学习 YOLOv11 与 OpenCV 实现人员跌倒识别系统(人体姿态估计版本)
  • 达梦数据库配置文件-COMPATIBLE_MODE
  • LangChain4j入门一:LangChain4j简介及核心概念
  • 路由基础(一):IP地址规划
  • 基于单片机空调温度控制测温ds18b20系统Proteus仿真(含全部资料)
  • React 组件命名规范:为什么必须大写首字母蛊傲
  • HarmonyOS安全开发实战:一套好用的数据加密方案
  • SQL Server 批量插入脚本
  • 中資券商櫃台系統搭建與開發技術分析
  • AI 大模型 “幻觉” 难题:为何会 “一本正经地说错话”,如何让它更靠谱?
  • 基于Cursor AI IDE的Vue3留言板系统实战:从零搭建到智能优化全流程
  • java数据类型获取长度方式总结
  • 【C++】C++11新特性第一弹(列表初始化、新式声明、范围for和STL中的变化)
  • Flutter 开发技巧 AI 快速构建 json_annotation model 的提示词