如何使用责任链模式优雅实现功能(滴滴司机、家政服务、请假审批等)
在企业级开发中,我们经常会遇到一系列有先后顺序、逐步处理的逻辑链路,例如请假审批、报销审批、日志处理、事件处理、滴滴司机接单流程等。这些场景非常适合使用 责任链模式(Chain of Responsibility Pattern) 来优雅地实现。
本文将详细介绍责任链模式的使用场景、结构设计、实现方式,并通过多个通用例子帮助你掌握这种强大的设计模式。
一、什么是责任链模式?
责任链模式是一种 行为型设计模式,它将一系列处理逻辑通过链式组合的方式连接在一起,让请求沿着链进行传递,直到某个处理器能够处理它为止。
通俗理解:就像一张请假单,需要班主任审批,班主任不够权限就交给年级主任,再不够交给校长……直到有人处理为止。
二、哪些场景适合使用责任链模式?
1. 多级审批流程
-
请假审批、报销审批
-
采购申请、项目审批
2. 分层服务处理
-
滴滴司机接单:顺序匹配附近的司机,直到有人接单
-
家政服务派单:按照服务区域和技能等级进行筛选
3. 日志记录
-
按等级过滤日志(DEBUG → INFO → ERROR)
4. 事件处理
-
Web 应用中多个拦截器/过滤器串联处理请求
-
消息队列的消息消费钩子链
5. 数据校验/敏感词过滤
-
多种规则依次校验,一旦命中规则即可终止处理
三、使用责任链模式的好处
优点 | 说明 |
---|---|
解耦 | 每个处理器只关心自己处理的职责,逻辑分离清晰 |
扩展性强 | 新增处理器不影响现有代码 |
灵活组合 | 可以动态组合处理器链路,适应不同场景 |
控制传递 | 可以灵活控制请求是否继续向下传递 |
四、如何使用责任链模式(实战步骤)
Step 1:定义责任链处理接口(或抽象类)
public abstract class Handler {protected Handler next;public void setNext(Handler next) {this.next = next;}public abstract void handle(Request request);
}
Step 2:定义具体处理器类
public class ManagerHandler extends Handler {@Overridepublic void handle(Request request) {if (request.getDays() <= 3) {System.out.println("经理审批通过");} else if (next != null) {next.handle(request);}}
}public class DirectorHandler extends Handler {@Overridepublic void handle(Request request) {if (request.getDays() <= 5) {System.out.println("总监审批通过");} else if (next != null) {next.handle(request);}}
}
Step 3:客户端构建责任链
public class Client {public static void main(String[] args) {Handler manager = new ManagerHandler();Handler director = new DirectorHandler();manager.setNext(director); // 形成链Request request = new Request(4); // 请假4天manager.handle(request);}
}
输出:
总监审批通过
五、实战案例简述(可拓展)
1. 滴滴司机接单流程
public class NearbyDriverFilter extends Handler {@Overridepublic void handle(OrderRequest request) {if (hasNearbyDriver(request)) {System.out.println("分配最近司机");} else if (next != null) {next.handle(request);}}
}
2. 报销审批流程
public class CFOHandler extends Handler {@Overridepublic void handle(Request request) {if (request.getAmount() < 10000) {System.out.println("CFO 审批通过");} else if (next != null) {next.handle(request);}}
}
六、使用责任链时的注意事项
1. 每个处理器职责要单一清晰
避免多个职责混合在一个处理器中,造成混乱。
2. 注意终止条件
处理器必须适时调用 next.handle()
,否则容易出现链条断裂或死循环。
3. 支持动态组合链条
可将处理器组合通过配置文件或容器注入方式来实现更高的灵活性。
4. 可添加中断机制
如:某处理器明确标识“中止处理”,不再继续向后传递。
七、责任链 VS 其他设计模式
模式 | 区别 |
---|---|
责任链 | 按顺序链式传递,直到处理结束 |
观察者 | 所有观察者都会响应通知 |
状态模式 | 处理器内部状态变更决定下个动作 |
策略模式 | 一次只选择一个策略处理,不传递链条 |
八、总结
责任链模式是一种非常实用且优雅的设计模式,适用于处理链式请求、审批流程、数据校验等场景。通过职责分明的链条结构,我们可以实现 高内聚、低耦合 的系统架构,提升代码可维护性与扩展性。
在实际项目中,责任链可与 Spring Boot、IOC容器、注解等结合,实现更强大的业务处理能力。
相关文章:
如何使用责任链模式优雅实现功能(滴滴司机、家政服务、请假审批等)
在企业级开发中,我们经常会遇到一系列有先后顺序、逐步处理的逻辑链路,例如请假审批、报销审批、日志处理、事件处理、滴滴司机接单流程等。这些场景非常适合使用 责任链模式(Chain of Responsibility Pattern) 来优雅地实现。 本…...
opencv的contours
1.哪里来的contours: 我们常常用到这一句: contours, hierarchy cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 输出的contours的是一个tuple类型的: 1.它的len()就是contour的个数 2.每一…...
使用 OpenCV 和 Dlib实现轮廓绘制
文章目录 引言1.准备工作2.代码解析2.1 导入必要的库2.2 定义绘制直线函数2.3 定义绘制凸包函数2.4 加载图像和模型2.5 关键点检测与绘制2.6 显示结果 3.68个关键点索引说明4.应用场景5.优化建议6. 结语 引言 人脸关键点检测是计算机视觉中的重要任务,广泛应用于人…...
学习黑客Linux 命令
在操作下面的闯关题之前,给下学习资料 一图速览:20 条命令及练习手册 #命令 & 常用参数关键作用典型练习1ls -alh列文件(含隐藏 & 人类可读大小)(数字海洋)在 $HOME 统计目录数2cd / pwd切换、显示路径cd /tmp &&a…...
探秘 RocketMQ 的 DLedgerServer:MemberState 的技术解析与深度剖析
在 RocketMQ 构建高可靠、强一致性消息系统的架构中,DLedgerServer 扮演着举足轻重的角色,而 MemberState 作为 DLedgerServer 内部用于描述节点状态的核心类,更是整个分布式日志模块稳定运行的关键。深入理解 MemberState 的设计理念、功能特…...
【计算机网络】HTTP中GET和POST的区别是什么?
从以下几个方面去说明: 1.定义 2.参数传递方式 3.安全性 4.幂等性 1.定义: GET: 获取资源,通常请求数据而不改变服务器的状态。POST: 提交数据到服务器,通常会改变服务器的状态或副作用(如创建或更新资源…...
C++负载均衡远程调用学习之Agent代理模块基础构建
目录 1.课程复习 2.Lars-lbAgentV0.1-udpserver启动 3.Lars-lbAgentV0.1-dns-reporter-client-thread启动 4.Lars-lbAgentV0.1-dns-client实现 5.Lars-lbAgentV0.1-dns-client编译错误修正 6.Lars-lbAgentV0.1-reporter_client实现 1.课程复习 ### 11.2 完成Lars Reactor…...
游戏开发的TypeScript(4)TypeScript 的一些内置函数
在 TypeScript 中,内置函数分为两类:JavaScript 原生函数(TypeScript 继承)和TypeScript 特有函数(类型系统相关)。以下是详细分类介绍: 一、JavaScript 原生函数 TypeScript 继承了所有 Java…...
软考 系统架构设计师系列知识点之杂项集萃(52)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(51) 第82题 以下关于系统性能的叙述中,不正确的是()。 A. 常见的Web服务器性能评估方法有基准测试、压力测试和可靠性测试 B. 评价Web服务器的主…...
大连理工大学选修课——图形学:第五章 二维变换及二维观察
第五章 二维变换及二维观察 二维变换 基本几何变换 图形的几何变换是指对图形的几何信息经过平移、比例、旋转等变换后产生新的图形。 基本几何变换都是相对于坐标原点和坐标轴进行的几何变换。 平移变换 推导: x ′ x T x y ′ y T y xxT_x\\ yyT_y x′xT…...
观察者模式(Observer Pattern)详解
文章目录 1. 什么是观察者模式?2. 为什么需要观察者模式?3. 观察者模式的核心概念4. 观察者模式的结构5. 观察者模式的基本实现简单的气象站示例6. 观察者模式的进阶实现推模型 vs 拉模型6.1 推模型(Push Model)6.2 拉模型(Pull Model)7. 观察者模式的复杂实现7.1 在线商…...
复刻低成本机械臂 SO-ARM100 标定篇
视频讲解: 复刻低成本机械臂 SO-ARM100 标定篇 组装完机械臂后,要进行初始标定,参考github的markdown lerobot/examples/10_use_so100.md at main huggingface/lerobot 只有从臂,所以arms里面只填follower即可 python lerobot…...
idea创建springboot工程-指定阿里云地址创建工程报错
idea创建springboot工程-指定阿里云地址创建工程报错 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】࿱…...
OpenStack HA高可用集群Train版-0集群环境准备
OpenStack HA高可用集群Train版-0集群环境准备 目录 主机配置1.主机名2.网卡配置网卡UUID配置主机名解析配置免密登录防火墙相关配置时间同步配置 二、基础软件安装数据库构建数据库集群设置心跳检测clustercheck准备脚本创建心跳检测用户,(任意控制节点)检测配置文件每个控制节…...
Python3与Dubbo3.1通讯解决方案(dubbo-python)
【文章非VIP可读,如果发现阅读限制为系统自动修改阅读权限,请留言我改回】 概述 最近AI项目需要java与python通讯,两边都是比较新的版本。因此需要双方进行通讯,在这里记录一下所采用的方案和关键点。 JAVA调用Python python通…...
深入探索 Java 区块链技术:从核心原理到企业级实践
一、Java 与区块链的天然契合 1.1 区块链技术的核心特征 区块链作为一种分布式账本技术,其核心特征包括: 去中心化:通过 P2P 网络实现节点自治,消除对中央机构的依赖。不可篡改性:利用哈希链和共识机制确保数据一旦…...
NV214NV217美光闪存固态NV218NV225
NV214NV217美光闪存固态NV218NV225 在当今数据驱动的时代,固态硬盘(SSD)的性能直接决定了计算系统的效率上限。美光科技作为全球存储解决方案的领军者,其NV系列产品凭借尖端技术持续刷新行业标准。本文将围绕NV214、NV217、NV218、…...
第三方组件库:element-uiiviewVant
第三方组件库:element-ui 使用方法: 1.引入样式 <!-- 引入element-ui样式 --><link rel"stylesheet" type"text/css" href"http://unpkg.com/view-design/dist/styles/iview.css">2.引入vue <!-- 引入Vue …...
Qt实现 hello world + 内存泄漏(5)
文章目录 实现hello world的两种方式通过图形化的方式通过纯代码的方式1. 新老头文件的说明2.堆或栈上创建对象的选择3.QString的说明 内存泄漏问题 实现hello world的两种方式 通过图形化的方式 通过图形化的方式,在界面上创建出一个控件,显示出hello …...
13:图像处理—畸变矫正详解
1.制作标定板和描述文件 (用PS软件打印) * 0.00375 mark 点间距 , 不是 点的直径//倒数第二个就是描述文件 gen_caltab(7,7,0.00375,0.5,caltab_30mm.descr,30-30.ps) * 1 比 1 打印 。Photoshop 格式 2.把标定板调正 调正的目的是为了…...
Prompt compress 技术探究-LLMLingua
Prompt summary:是通过精心设计的提示词(prompt)引导大型语言模型(如 GPT-4)生成特定风格或结构的摘要。其目标不仅是压缩信息,还包括满足特定的格式要求、风格偏好或任务需求,所以和一般的文本…...
Python|Pyppeteer实现自动登录小红书(32)
前言 本文是该专栏的第32篇,结合优质项目案例持续分享Pyppeteer的干货知识,记得关注。 本文中,笔者以小红书为例,基于Pyppeteer实现自动登录“小红书”。 需要注意的是,对Pyppeteer不太熟悉的同学,可往前翻阅本专栏前面介绍的Pyppeteer知识点,本专栏将带你了解并熟练使…...
Milvus(13):自定义分析器、过滤器
1 自定义分析器 1.1 标准标记符 Milvus 中的standard 令牌分割器根据空格和标点符号分割文本,适用于大多数语言。要配置使用standard 令牌转换器的分析器,请在analyzer_params 中将tokenizer 设置为standard 。 analyzer_params {"tokenizer&quo…...
调试Cortex-M85 MCU启动汇编和链接命令文件 - 解题一则
调试Cortex-M85 MCU启动汇编和链接命令文件 - 解题一则 苏勇 Andrew, 2025-05 最近在Keil中调试一款新的Cortex-M85内核MCU的SDK代码时,从原有其它芯片的工程中引入了汇编语言编写的启动代码和配套的sct文件,结果总是报错,清理到最后&#…...
SpringMVC——第五章:视图View
一、SpringMVC中视图的实现原理 1.Spring MVC视图支持可配置 在Spring MVC中,视图View是支持定制的,例如我们之前在 springmvc.xml 文件中进行了如下的配置: <!--视图解析器--> <bean id"thymeleafViewResolver" class…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】3.4 数据重复与去重(IDENTITY COLUMN/UNIQUE约束)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL数据分析实战:数据质量分析之数据重复与去重(IDENTITY COLUMN/UNIQUE约束)3.4 数据重复与去重3.4.1 数据重复的影响与识别3.4.…...
数据分析之药物-基因-代谢物
记录一下最近的数据分析过程: 假如我有一个Dataframe,有两列[Drug, Gene],我想构造一个矩阵,行名为Drug,列名为Gene,值为0或者1,其中0表示药物的靶点是该基因,0表示不是靶点。 &am…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】3.2 缺失值检测与处理(NULL值填充/删除策略)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 缺失值检测与处理全攻略:NULL值填充与删除策略实战3.2 缺失值检测与处理3.2.1 缺失值类型与业务影响3.2.1.1 缺失值的三种形态3.2.1.2 业务影响分级 3.2.2 缺失值…...
科普简洁版:同态加密——密码学的未来瑰宝
文章目录 一、同态加密的基本概念1.1 什么是同态加密1.2 同态加密的数学本质1.3 同态加密的类型 二、主要同态加密方案详解2.1 ElGamal加密2.2 Paillier加密2.3 Gentry的完全同态加密方案2.4 BGV方案2.5 BFV方案2.6 CKKS方案 三、同态加密的关键技术3.1 噪声管理技术3.2 多项式…...
时序分解 | Matlab基于WOA-MVMD鲸鱼算法优化多元变分模态分解
时序分解 | Matlab基于WOA-MVMD鲸鱼算法优化多元变分模态分解 目录 时序分解 | Matlab基于WOA-MVMD鲸鱼算法优化多元变分模态分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 WOA-MVMD鲸鱼算法优化多元变分模态分解时间序列信号分解 可直接运行 分解效果好 适合作为创…...
模型部署与提供服务
工具准备 FastApi (提供接口服务) LLamafactory(模型测试) AutoDL-SSH(隧道工具) 结构目录 app ├── api.sh ├── lawbot_infer.py ├── main.py ├── models.py ├── prompts │ ├── chat.jinja2 │ ├── prediction.jinja2 │…...
【Linux】深入理解程序地址空间
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、什么是程序地址空间 二、深入理解程序地址空间 1. 引例 2. 理解地址转化 3. 再谈程序地址空间 4. 补充知识 总结 前言 在现代操作系…...
基于AWS Marketplace的快速解决方案:从选型到部署实战
1. 引言:为什么选择AWS Marketplace? 在数字化转型的背景下,企业需要快速获取成熟的软件工具和服务以降低开发成本。AWS Marketplace 作为亚马逊云科技的官方应用商店,提供超过万款预配置的第三方和AWS原生解决方案,涵…...
Android 常用输入控件
一 控件名称 TextView二 示例代码 <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.a…...
ubuntu修改时区和设置24小时格式时间
这里写目录标题 一、修改时区二、设置24小时格式时间endl 一、修改时区 使用timedatectl命令更改当前时区为东八区[rootubuntu24-16:~]# timedatectl list-timezones | grep -i shanghai Asia/Shanghai [rootubuntu24-16:~]# timedatectl set-timezone Asia/Shanghai [rootubu…...
Android之Button、ImageButton、ChipGroup用法
一 控件名称及UI代码 Button、ImageButton、ChipGroup <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app=&qu…...
【中间件】brpc_基础_用户态线程中断
bthread之用户态线程中断 源码 1 简介 interrupt_pthread 核心功能是 通过信号机制中断阻塞的 pthread 线程,以实现线程的协作式中断。 2 核心功能与设计 2.1 信号选择与注册 信号选择:使用 SIGURG 作为中断信号。 原因:SIGURG 通常用于…...
MATLAB中tabulate函数——先验概率的简单估计
load fisheriris X meas(:,1:2); Y species; labels unique(Y); tabulate(Y)ValueCountPercentsetosa5033.33%versicolor5033.33%virginica5033.33%...
修复笔记:SkyReels-V2 项目中的 torch.load 警告
#工作记录 一、问题描述 在运行项目时,出现以下警告: FutureWarning: You are using torch.load with weights_onlyFalse (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pic…...
[特殊字符] 人工智能大模型之开源大语言模型汇总(国内外开源项目模型汇总) [特殊字符]
Large Language Model (LLM) 即大规模语言模型,是一种基于深度学习的自然语言处理模型,它能够学习到自然语言的语法和语义,从而可以生成人类可读的文本。 所谓 "语言模型",就是只用来处理语言文字(或者符号…...
自监督学习(Self-supervised Learning)李宏毅
目录 Self-supervised Learning简介: BERT : How to use BERT case1:sequence to class 语言积极性OR消极性判断 case2:sequence to sequence句子中的词语词性标注 case3:sequence2 to class两个句子是不是一个为前提一个为…...
数字化时代下,软件测试中的渗透测试是如何保障安全的?
在如今数字化与信息化的时代,软件测试中存在渗透测试,其位置十分重要,它借助模拟恶意攻击的方式,去发现软件系统所存在的漏洞以及安全问题,这是保障软件安全的关键环节,接下来我会对它的各个方面进行详细介…...
内容中台的AI中枢是什么?
智能算法与知识图谱融合引擎 现代内容中台的核心竞争力在于智能算法与知识图谱的深度融合,这种技术组合构建了动态演化的认知网络。通过将机器学习模型与领域知识图谱进行耦合,系统不仅能识别文本、图像、视频等多模态数据的关联特征,还能实…...
PostgreSQL 的 REINDEX 命令
PostgreSQL 的 REINDEX 命令 REINDEX 是 PostgreSQL 中用于重建索引的重要命令,它可以解决索引损坏、索引膨胀或性能下降等问题。 一 REINDEX 基本语法 -- 重建单个索引 REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA } [ CONCURRENTLY ] name REIND…...
GNOME扩展:Bing壁纸
难点 网络请求(Soup) 下载文件(Soup) 读写设置(Gio.Settings) 源码 import GLib from "gi://GLib"; import Gio from gi://Gio; import St from gi://St; import Soup from gi://Soup;import { Extension } from resource:///org/gnome/shell/extensions/extens…...
BUUCTF——Fake XML cookbook
BUUCTF——Fake XML cookbook 进入靶场 只有一个登录框 先弱口令万能密码试一下吧 弱口令和万能密码都失败了 找其他突破口 F12看看 发现xml代码 function doLogin(){var username $("#username").val();var password $("#password").val();if(user…...
【数据结构】线性表--链表
【数据结构】线性表--链表 一.前情回顾二.链表的概念三.链表的实现1.链表结点的结构:2.申请新结点函数:3.尾插函数:4.头插函数:5.尾删函数:6.头删函数:7.在指定结点之前插入:8.在指定结点之后插…...
2022年第十三届蓝桥杯省赛B组Java题解
2022年第十三届蓝桥杯省赛B组Java题解 个人心得: 2022年蓝桥杯省赛Java B组共包含10道题目,其中填空题2道(A、B),编程题8道(C-J)。题目覆盖数论、字符串处理、动态规划、数据结构等核心知识点…...
【操作系统】死锁
1. 定义 死锁是指两个或多个进程(或线程)在执行过程中,因争夺资源而造成的一种僵局,每个进程都无限期地等待其他进程释放它们所持有的资源。在这种情况下,没有任何进程能够继续执行,除非有外部干预。 2. …...
Ubuntu22.04及以上版本buildroot SIGSTKSZ 报错问题
本文提供一种解决 Buildroot SIGSTKSZ 报错途径 解决途径来源参考:Buildroot error when building with Ubuntu 21.10 其出现原因在于 GNU C Library 2.34 release announcement: Add _SC_MINSIGSTKSZ and _SC_SIGSTKSZ. When _DYNAMIC_STACK_SIZE_SOU…...