谁该处理我的请假?——责任链模式
谁该处理我的请假?——责任链模式
- 一、生活中的责任链:请假审批流程
- 二、责任链模式的核心特点
- 三、代码实现:请假审批责任链
- 四、工作中的实际应用场景
- 五、框架中的经典应用
- 六、模式本质理解
一、生活中的责任链:请假审批流程
想象一个公司请假流程:员工提交申请后,1天内小组长审批,1-3天需部门经理审批,超过3天由CTO审批。每个审批人只关注自己权限范围内的请求,若超出权限则自动转交下一级。这种"接力式处理"的机制,就是责任链模式的典型应用
二、责任链模式的核心特点
特点:
- 解耦性强:请求发送者无需知道具体处理者,处理者之间无需知道彼此的存在。(员工只需提交申请,无需关心谁来审批)
- 动态扩展灵活:新增审批环节只需添加新处理器,无需修改原有代码。(增加HR总监审批只需新增一个Handler)
- 职责单一:每个处理者只处理自己职责范围内的任务。(小组长不处理超过1天的申请)
缺点注意点:
- 长链条可能影响性能
- 客户端需正确配置链条,否则易出错
- 请求可能未被处理(如责任链断裂)
三、代码实现:请假审批责任链
完整代码示例:
// 抽象审批处理器
public abstract class ApproveHandler {protected ApproveHandler next; // 链式关键:保存下一个节点public void setNext(ApproveHandler next) {this.next = next;}public abstract void handleRequest(int days);
}// 小组长审批(处理1天以内)
public class GroupLeaderHandler extends ApproveHandler {@Overridepublic void handleRequest(int days) {if (days <= 1) {System.out.println("小组长审批通过:请假" + days + "天");} else if (next != null) {next.handleRequest(days); // 转交下一节点}}
}// 部门经理审批(处理1-3天)
public class DeptManagerHandler extends ApproveHandler {@Overridepublic void handleRequest(int days) {if (days > 1 && days <= 3) {System.out.println("部门经理审批通过:请假" + days + "天");} else if (next != null) {next.handleRequest(days);}}
}// CTO审批(处理3天以上)
public class CTOHandler extends ApproveHandler {@Overridepublic void handleRequest(int days) {if (days > 3) {System.out.println("CTO审批通过:请假" + days + "天");} else if (next != null) {next.handleRequest(days);}}
}// 客户端调用
public class Client {public static void main(String[] args) {// 构建责任链ApproveHandler groupLeader = new GroupLeaderHandler();ApproveHandler deptManager = new DeptManagerHandler();ApproveHandler cto = new CTOHandler();groupLeader.setNext(deptManager);deptManager.setNext(cto);// 发起请假请求groupLeader.handleRequest(2); // 部门经理处理groupLeader.handleRequest(5); // CTO处理}
}
输出结果:
部门经理审批通过:请假2天
CTO审批通过:请假5天
四、工作中的实际应用场景
多级审批系统
- 请假、报销、采购等流程审批
- 敏感操作需多级领导确认(如服务器重启)
数据校验链
- 用户注册时的非空校验、格式校验、重复性校验
- 金融交易前的风控规则校验
异常处理机制
- 程序异常捕获时,逐级尝试恢复策略
- 网络请求失败后的重试机制(如先重试3次,再切换备用服务器)
五、框架中的经典应用
Servlet Filter
请求依次经过编码过滤器、权限过滤器、日志过滤器等
public class LogFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {System.out.println("请求开始时间:" + new Date());chain.doFilter(req, res); // 传递给下一个FilterSystem.out.println("请求结束时间:" + new Date());}
}
Spring Interceptor
拦截器链实现权限检查、参数预处理等
public class AuthInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {if (!checkToken(request)) {return false; // 中断请求}return true; // 继续传递}
}
日志级别处理
DEBUG→INFO→WARN→ERROR逐级传递,直到找到匹配级别的处理器
六、模式本质理解
责任链模式像一场流程接力赛:
- 每个选手(处理器)专注自己的赛道(业务范围)
- 接力棒(请求)自动传递给下个选手
- 裁判(客户端)只需发令,无需干预比赛过程
这种设计让复杂流程变得像搭积木一样灵活,是处理多层级、多条件业务的利器。通过合理运用,能显著提升代码的可维护性和扩展性。
相关文章:
谁该处理我的请假?——责任链模式
谁该处理我的请假?——责任链模式 一、生活中的责任链:请假审批流程二、责任链模式的核心特点三、代码实现:请假审批责任链四、工作中的实际应用场景五、框架中的经典应用六、模式本质理解 一、生活中的责任链:请假审批流程 想象…...
【NLP应用场景全解】自然语言处理如何改变世界?
自然语言处理作为人工智能的重要分支,正在加速改变各行各业。根据Statista预测,到2025年,全球NLP市场规模将达到438亿美元。本文将系统梳理NLP的主要应用场景,结合最新技术趋势,帮助你了解NLP技术的落地现状与未来发展…...
Hive 中书写SQL注意的地方
1.1 关于 DDL (1)创建带有主键约束的 Hive 表时报错。 Hive 目前还没有严格支持“主键约束”,创建带有主键约束的 HIVE 表时报了如下错误: SemanticException [Error 10326]: Invalid Constraint: syntax ENABLE/ENFORCED featu…...
Ubuntu 下 无界面环境 多进程/多线程 使用DrissionPage
使用wget “https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb” -O chrome.deb 安装chrome # !/usr/bin/python3 # -*- coding:utf-8 -*- """ author: JHC000abcgmail.com file: dp.py time: 2025/2/20 20:22 desc:wget "htt…...
Opencv计算机视觉编程攻略-第十节 估算图像之间的投影关系
目录 1. 计算图像对的基础矩阵 2. 用RANSAC 算法匹配图像 3. 计算两幅图像之间的单应矩阵 4. 检测图像中的平面目标 图像通常是由数码相机拍摄的,它通过透镜投射光线成像,是三维场景在二维平面上的投影,这表明场景和它的图像之间以及同一…...
RocketMQ 01
今天是2025/04/06 21:31 day 18 总路线请移步主页Java大纲相关文章 今天进行RocketMQ 1,2 个模块的归纳 首先是RocketMQ 的相关内容概括的思维导图 1. 核心组件 1.1 NameServer 核心功能 服务发现:作为轻量级注册中心,管理所有 Broker 的地址和路由信…...
牛客周赛———字符串
题目如下 思路(贪心) >和<的位置是固定不变的,所以先处理这两个符号,然后再遍历一遍检查‘Z’,如果不符合条件将Z的位置改变正负性使其满足条件,然后遍历的时候记数答案就行了,注意s的首…...
在Hive中,将数据从一个表查询并插入到另一个表
1. 确认目标表结构 确保目标表已存在且结构与查询结果匹配。若不存在,需先创建: CREATE TABLE target_table ( id INT, name STRING ) PARTITIONED BY (dt STRING) STORED AS ORC; 2. 选择插入方式 覆盖插入(替换现有数据࿰…...
优雅实现级联选择器:CascadeSelect 类设计与实现
在现代Web开发中,级联选择器是一种常见的UI组件,它能够有效地组织和展示层级数据。本文将深入解析一个功能完善的级联选择器实现——CascadeSelect类,展示如何用面向对象的方式构建可复用的UI组件。 组件概述 CascadeSelect是一个二级下拉框…...
26考研 | 王道 | 数据结构 | 第五章 树
第五章 树 5.1. 树的概念 5.1.1. 树的基本定义 树:n(n>0)个节点的有限集合,是一种逻辑结构,当n0时为空树,且非空树满足: 有且仅有一个特定的称为根的节点当n>1时,其余结点可分为m (m >0) 个互不相交的有限集合&#x…...
Spring 怎么解决循环依赖问题?
Spring 循环依赖(circular dependency) 指的是多个 Bean 之间的相互依赖,比如: A 依赖 B,B 又依赖 A;或者 A → B → C → A 这种嵌套循环依赖。 这是一个常见又棘手的问题,但 Spring 是可以解…...
微软推出首款量子计算芯片Majorana 1
全球首款拓扑架构量子芯片问世,2025年2月20日,经过近20年研究,微软推出了首款量子计算芯片Majorana 1,其宣传视频如本文末尾所示。 微软表示,开发Majorana 1需要创造一种全新的物质状态,即所谓的“拓扑体”…...
OSI模型中协议数据单元(PDU)
OSI模型中协议数据单元(PDU) 协议数据单元(Protocol Data Unit, PDU)是网络通信中每一层协议处理的数据单位,其内容和格式由特定层的协议定义。PDU在不同OSI层次中有不同的名称和结构,体现了分层模型的核心…...
代码训练营day24 回溯算法
回溯算法part03 93.复原IP地址 题目链接/文章讲解:代码随想录 视频讲解:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili 本题关键在于终止条件 插入3个’.’时判断 ip地址最后一段是否…...
DP Alt Mode 与 DP协议的关系
1. 什么是 “Alt Mode”(替代模式)? Alt Mode(Alternative Mode) 是 USB Type-C 接口 的扩展协议机制,允许通过 物理接口复用(Pin Reuse) 将USB-C接口动态切换为其他协议࿰…...
【欧拉筛】哥德巴赫猜想题解
哥德巴赫猜想题解 题目传送门 1292. 哥德巴赫猜想 一、题目描述 哥德巴赫猜想指出:任意一个大于4的偶数都可以拆成两个奇素数之和。给定多个偶数(6 ≤ n < 10^6),验证它们是否符合这个猜想。对于每个偶数,输出其素数分解中两数差最大的…...
A*算法详解及Python实现
一、什么是A*算法? A*(读作"A-star")算法是一种广泛使用的路径查找和图形遍历算法,它结合了Dijkstra算法的完备性和贪婪最佳优先搜索的高效性。A*算法通过使用启发式函数来估算从当前节点到目标节点的成本,…...
【C++】第九节—string类(中)——详解+代码示例
hello! 云边有个稻草人-CSDN博客 C_云边有个稻草人的博客-CSDN博客 菜鸡进化中。。。 目录 【补充】 二、string类里面的常用接口 1.resize 2.insert 3.assign 4.erase 5.replacefind 6.c_str 7.rfindsubstr 8.find_first_of、find_last_of、find_first…...
vite.config.js常用配置
vite 是一个基于 Vue3 单文件组件的非打包开发服务器,它做到了本地快速开发启动: 快速的冷启动,不需要等待打包操作; 即时的热模块更新,替换性能和模块数量的解耦让更新飞起; 真正的按需编译,不…...
【C++11(下)】—— 我与C++的不解之缘(三十二)
前言 随着 C11 的引入,现代 C 语言在语法层面上变得更加灵活、简洁。其中最受欢迎的新特性之一就是 lambda 表达式(Lambda Expression),它让我们可以在函数内部直接定义匿名函数。配合 std::function 包装器 使用,可以…...
李臻20242817_安全文件传输系统项目报告_第6周
安全文件传输系统项目报告(第 1 周) 1. 代码链接 Gitee 仓库地址:https://gitee.com/li-zhen1215/homework/tree/master/Secure-file 代码结构说明: project-root/├── src/ # 源代码目录│ ├── main.c # 主程序入口│ ├…...
使用SymPy求解矩阵微分方程
引言 在数学、物理、工程等领域,微分方程常常被用来描述系统的变化和动态过程。对于多变量系统或者多方程系统,矩阵微分方程是非常常见的,它可以用来描述如电路、控制系统、振动系统等复杂的动态行为。今天,我们将通过Python 中的 SymPy 库来求解矩阵微分方程,帮助大家轻…...
Flutter之用户输入网络数据缓存
目录: 1、处理用户输入1.1、按钮1.2、文本1.3、富文本1.4、TextField1.5、Form 2、复选框、Switch 和 Radio2.1、复选框2.2、Switch2.3、Radio 3、选择日期或时间4、滑动5、网络和数据6、本地缓存6.1、在本地内存中缓存数据 7、web端和Flutter样式控制对比7.1、文本…...
华为IP(4)
VRRP(虚拟路由冗余协议) 前言: 局域网中的用户终端通常采用配置一个默认网关的形式访问外部网络,如果默认网关设备发生故障,那么所有用户终端访问外部网络的流量将会中断。可以通过部署多个网关的方式来解决单点故障…...
蓝桥杯刷题周计划(第四周)
目录 前言题目一题目代码题解分析 题目二题目代码题解分析 题目三题目代码题解分析 题目四题目代码题解分析 题目五题目代码题解分析 题目六题目代码题解分析 题目七题目代码题解分析 题目八题目代码题解分析 题目九题目代码题解分析 题目十题目代码题解分析题目代码题解分析 题…...
华为网路设备学习-17
目录 一、加密算法 二、验证算法 三、IPsec协议 1.IKE协议(密钥交换协议) ①ISAKMP(Internet Security Association and Key Management Protocol)互联网安全关联和密钥管理协议 ②安全关联(SA) ③…...
【动态规划】深入动态规划 非连续子序列问题
文章目录 前言例题一、最长递增子序列二、摆动序列三、最长递增子序列的个数四、最长数对链五、最长定差子序列六、最长的斐波那契子序列的长度七、最长等差数列八、等差数列划分II - 子序列 结语 前言 什么是动态规划中的非连续子序列问题? 动态规划中的非连续子序…...
灵魂拷问,指针为什么是C语言的灵魂?
目录 | 引 言 | 内存操作 | 构造复杂的数据结构 | 底层硬件交互 | 指针的陷阱 | 文 末 | 引 言 指针是C语言的灵魂! 这句话是不是很耳熟?但为什么这么说,你知道吗? 本篇小文就从内存、数据结构、底层硬件交互这三个维度来…...
Node.js自定义中间件
目录 Node.js 自定义中间件详细介绍 1. 目录结构 2. 什么是自定义中间件? 3. 代码实现 1. 自定义日志中间件(记录请求信息) 2. 自定义身份验证中间件(校验用户权限) 3. 自定义请求时间中间件(记录请…...
Qt 音乐播放器项目
具体代码见:https://gitee.com/Suinnnnnn/MusicPlayer 文章目录 0. 预备1. 界面1.1 各部位长度1.2 ui文件1.3 窗口前置设置1.4 设置QSS 2. 自定义控件2.1 按钮2.2 推荐页面2.3 CommonPage2.4 滑杆 3. 音乐管理4. 歌词界面4.1 ui文件4.2 LrcPage.h文件 5. 音乐播放控…...
初识数据结构——Java集合框架解析:List与ArrayList的完美结合
📚 Java集合框架解析:List与ArrayList的完美结合 🌟 前言:为什么我们需要List和ArrayList? 在日常开发中,我们经常需要处理一组数据。想象一下,如果你要管理一个班级的学生名单,或…...
LightRAG实战:轻松构建知识图谱,破解传统RAG多跳推理难题
作者:后端小肥肠 🍊 有疑问可私信或评论区联系我。 🥑 创作不易未经允许严禁转载。 姊妹篇: 2025防失业预警:不会用DeepSeek-RAG建知识库的人正在被淘汰_deepseek-embedding-CSDN博客 从PDF到精准答案:Coze…...
Hyperlane框架全面详解与应用指南 [特殊字符][特殊字符][特殊字符]
Hyperlane框架全面详解与应用指南 🚀🚀🚀 📚 前言 欢迎来到Hyperlane框架的全面详解与应用指南!🎉🎉🎉 本文档旨在为开发者提供一个全面、详尽的Hyperlane框架使用指南,…...
使用LVS的 NAT 模式实现 3 台RS的轮询访问
题目 使用LVS的 NAT 模式实现 3 台RS的轮询访问。IP地址和主机自己规划。 -i— turn,-g——DR模式,-m——NAT模式 节点规划 仅主机网段:192.168.216.0/24 NAT网段:192.168.88.0/24 主机角色系统网络ipclientclientredhat9.5仅…...
BGP路由协议之属性4
MED 多出口鉴别器 可选非过渡属性 EBGP 的邻居 Cost 开销值,控制如何进入 AS。越小越优。继承 IGP 的开销值,默认 0 MED(Multi-Exit Discriminator,多出口鉴别器)是可选非过属性,是一种度量值用于向外部对等体指出进入本 AS 的首…...
数据库的操作
1.创建数据库 CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] ...]create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 大写的表示关键字。[]是可选项。CHARACTER SET:指定…...
【愚公系列】《高效使用DeepSeek》055-可靠性评估与提升
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...
记录clickhouse记录一次性能优化,从60s到1s
文章目录 问题表结构类似如下分析第一步调整第一步观察多磁盘读继续观察sql 问题 一个查询接口,涉及多个clickhouse 查询,查询用时一下变成要60s 表结构类似如下 CREATE TABLE demo.test_local (id UUID,date DateTime,type String ) ENGINE Replic…...
二叉树的层序遍历
102. Binary Tree Level Order Traversal 广度优先搜索 将每个结点的层号记录下。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* …...
嵌入式硬件篇---TOF陀螺仪SPI液晶屏
文章目录 前言1. TOF传感器(Time of Flight)原理STM32使用方法硬件连接SDASCLVCC\GND 软件配置初始化I2C外设库函数驱动:读取数据 2. 陀螺仪(如MPU6050)原理STM32使用方法硬件连接SDA/SCLINTVCC/GND 软件配置初始化I2C…...
OpenCV 在树莓派上进行实时人脸检测
这段 Python 代码借助 OpenCV 库实现了在树莓派上进行实时人脸检测的功能。它会开启摄像头捕获视频帧,在每一帧里检测人脸并以矩形框标记出来,同时在画面上显示帧率(FPS)。 依赖库 cv2:OpenCV 库,用于计算…...
55.跳跃游戏
题目来源: leetcode题目,网址:55. 跳跃游戏 - 力扣(LeetCode) 解题思路: 遍历数组,若当前节点可达,更新可到达的最远距离,否则返回false。若可遍历整个数组…...
awk 实现listagg ,count 功能
awk命令实现分组统计 测试数据 ABC a1 ABC a2 ABC a3 ABD c1 ABD c2 分组统计 abc a1,a2,a3 3 abd c1,c2 awk 命令 awk {arr[$1]arr[$1] ? arr[$1] "," $2 : $2; count[$1]} END{for (i in arr) print tolower(i), arr[i], count[i]} group_…...
瑞萨RA4M2使用心得-GPIO输出
目录 一、新建项目 二、图形化开发 1.初始化IO 2.界面介绍 3.代码编写 4.所有内部函数的封装位置 5.LED闪烁函数编写 三.debug运行 总结 环境: 开发板:RA-Eco-RA4M2-100PIN-V1.0 IDE:e2 studio 一、新建项目 正常操作,下…...
uniapp微信小程序引入vant组件库
1、首先要有uniapp项目,根据vant官方文档使用yarn或npm安装依赖: 1、 yarn init 或 npm init2、 # 通过 npm 安装npm i vant/weapp -S --production# 通过 yarn 安装yarn add vant/weapp --production# 安装 0.x 版本npm i vant-weapp -S --production …...
COZE通关指南:工作流与插件开发
前言 本文隶属于专栏《AI Agent 通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《AI Agent 通关指南》 正文 1. 平台基础介绍 🌟 1.1 COZE平台概述 COZE平台(coze.cn)是一个强大的AI应用开发平台…...
在Unity中,如果物体上的脚本丢失,可以通过编写一个自定义编辑器脚本来查找并删除这些丢失的组件
在Unity中,如果物体上的脚本丢失,可以通过编写一个自定义编辑器脚本来查找并删除这些丢失的组件。以下是一个示例脚本,它可以帮助你一键检索场景中所有丢失脚本的物体,并删除这些丢失的组件。 步骤: 创建编辑器脚本&a…...
青少年编程与数学 02-016 Python数据结构与算法 04课题、栈与队列
青少年编程与数学 02-016 Python数据结构与算法 04课题、栈与队列 一、栈1. 栈的定义2. 栈的特点3. 栈的基本操作示例 4. 栈的实现(1)数组实现(2)链表实现 5. 栈的应用(1)函数调用(2)…...
Lucene.Net全文搜索引擎:架构解析与全流程实战指南
文章目录 引言:为什么选择Lucene.Net?一、Lucene.Net核心架构剖析1.1 模块化设计 二、Lucene.Net索引原理揭秘2.1 倒排索引:搜索的基石2.2 段(Segment)机制 三、全流程实战:从0到1构建搜索引擎3.1 环境准备…...
OpenSceneGraph 中的 LOD详解
LOD (Level of Detail,细节层次) 是3D图形中一种重要的优化技术,OpenSceneGraph 通过 osg::LOD 类提供了完整的LOD支持。 一、LOD 基本概念 1. 什么是LOD 核心思想:根据物体与相机的距离显示不同细节程度的模型 目的:减少远处物…...