责任链模式_行为型_GOF23
责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,核心思想是将多个处理请求的对象连成一条链,请求沿链传递直到被处理。它像现实中的“多级审批流程”——请假或报销时,申请会逐级提交给不同权限的领导,直到有人能处理为止。
一、通俗理解
假设你开发一个多级审批系统:
- 传统方式:用大量
if-else判断不同金额的报销单由谁审批,代码臃肿且难以扩展。 - 责任链模式:
- 抽象审批人:定义统一的处理接口,并持有下一级审批人的引用。
- 具体审批人(如组长、经理、CEO):各自处理权限内的请求,超出权限则转交下一级。
最终只需将审批人连成链,客户端提交请求到链头,无需关心具体处理细节。
二、模式结构
- 抽象处理者(Handler):定义处理请求的接口,包含设置下一处理者的方法(如
setNext())。 - 具体处理者(ConcreteHandler):实现处理逻辑,若无法处理则转交下一级。
- 客户端(Client):创建处理链,发起请求。
三、适用场景
- 多级审批流程:如请假、报销、工单处理。
- 动态扩展处理逻辑:如日志过滤器、权限验证链。
- 请求发送者与接收者解耦:如 GUI 事件传递、网络请求拦截器。
四、代码实现
1. C++ 示例(报销审批链)
#include <iostream> // 抽象处理者
class Approver {
protected: Approver* next = nullptr;
public: void setNext(Approver* nextApprover) { next = nextApprover; } virtual void handle(int amount) = 0;
}; // 具体处理者:组长
class GroupLeader : public Approver {
public: void handle(int amount) override { if (amount <= 1000) { std::cout << "组长审批通过(金额:" << amount << "元)" << std::endl; } else if (next) { next->handle(amount); } else { std::cout << "无人能处理此金额!" << std::endl; } }
}; // 具体处理者:经理
class Manager : public Approver {
public: void handle(int amount) override { if (amount <= 5000) { std::cout << "经理审批通过(金额:" << amount << "元)" << std::endl; } else if (next) { next->handle(amount); } }
}; int main() { GroupLeader leader; Manager manager; leader.setNext(&manager); leader.handle(800); // 组长处理 leader.handle(3000); // 经理处理 leader.handle(10000); // 无处理 return 0;
}
输出:
组长审批通过(金额:800元)
经理审批通过(金额:3000元)
无人能处理此金额!
解析:
- 组长处理 ≤1000 元的请求,否则转交经理。
- 经理处理 ≤5000 元的请求,更高金额无后续处理者。
2. Python 示例(日志过滤器链)
from abc import ABC, abstractmethod class LogHandler(ABC): def __init__(self): self.next = None def set_next(self, next_handler): self.next = next_handler @abstractmethod def handle(self, log_level, message): pass class DebugHandler(LogHandler): def handle(self, log_level, message): if log_level == "DEBUG": print(f"[DEBUG] {message}") elif self.next: self.next.handle(log_level, message) class ErrorHandler(LogHandler): def handle(self, log_level, message): if log_level == "ERROR": print(f"[ERROR] {message}") elif self.next: self.next.handle(log_level, message) # 客户端
debug = DebugHandler()
error = ErrorHandler()
debug.set_next(error) debug.handle("DEBUG", "调试信息") # [DEBUG] 调试信息
debug.handle("ERROR", "系统崩溃") # [ERROR] 系统崩溃
debug.handle("INFO", "普通日志") # 无输出
解析:
DebugHandler处理DEBUG日志,其他级别转交下一处理者。- 链式调用避免硬编码日志级别判断。
3. Java 示例(请假审批系统)
// 抽象处理者
abstract class Approver { protected Approver next; public void setNext(Approver next) { this.next = next; } public abstract void handle(int days);
} // 具体处理者:组长
class GroupLeader extends Approver { @Override public void handle(int days) { if (days <= 3) { System.out.println("组长批准请假 " + days + "天"); } else if (next != null) { next.handle(days); } }
} // 具体处理者:经理
class Manager extends Approver { @Override public void handle(int days) { if (days <= 7) { System.out.println("经理批准请假 " + days + "天"); } else if (next != null) { next.handle(days); } }
} public class Client { public static void main(String[] args) { GroupLeader leader = new GroupLeader(); Manager manager = new Manager(); leader.setNext(manager); leader.handle(2); // 组长处理 leader.handle(5); // 经理处理 leader.handle(10); // 无处理 }
}
输出:
组长批准请假 2天
经理批准请假 5天
解析:
- 组长处理 ≤3 天的请假,其余转交经理。
- 责任链动态组合,新增审批人只需扩展链。
五、优缺点分析
| 优点 | 缺点 |
|---|---|
| 1. 解耦请求与处理逻辑:客户端无需知道具体处理者 | 1. 性能问题:长链可能导致请求传递慢 |
| 2. 灵活扩展:动态增减处理节点,符合开闭原则 | 2. 调试困难:请求可能未被处理或循环传递 |
| 3. 单一职责:每个处理者专注自身逻辑 | 3. 链配置错误风险:需确保链正确连接 |
六、总结
责任链模式通过链式传递请求,实现了处理逻辑的动态组合与解耦。适用于多级审批、日志过滤等场景,但需注意链长控制和错误处理。其核心价值在于:
- 灵活扩展:新增处理者无需修改原有代码。
- 职责分离:每个处理者只关注自身任务。
- 实际应用:如 Spring MVC 的拦截器链、Netty 的 ChannelPipeline。
相关文章:
责任链模式_行为型_GOF23
责任链模式 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,核心思想是将多个处理请求的对象连成一条链,请求沿链传递直到被处理。它像现实中的“多级审批流程”——请假或报销时,申请会逐级提交给…...
03-SpringBoot3入门-配置文件(自定义配置及读取)
1、自定义配置 # 自定义配置 zbj:user:username: rootpassword: 123456# 自定义集合gfs:- a- b- c2、读取 1)User类 package com.sgu.pojo;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.spring…...
学习记录-软件测试基础
一、软件测试分类 1.按阶段:单元测试(一般开发自测)、集成测试、系统测试、验收测试 2.按代码可见度测试:黑盒测试、灰盒测试、白盒测试 3.其他:冒烟测试(冒烟测试主要是在开发提测后进行,主要是测试主流…...
【蓝桥杯每日一题】3.28
🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x "今天熬的夜,会变成明天奖状的闪光点!" 目录 一、唯一的雪花 题目链接 题目描述 解题思路 解题代码 二、逛画展 题目链接 题目描述 解题思路 解题代…...
优秀的 React 入门开源项目推荐
以下是一些优秀的 React 入门开源项目推荐,涵盖不同应用场景和功能模块,适合学习和实践: 1. Jira Clone 仓库地址:GitHub - oldboyxx/jira_clone 亮点: 基于 React Hooks 实现,模仿 Jira 的任务管理功能。…...
万字长文详解Text-to-SQL
什么是Text-to-SQL 在各个企业数据量暴涨的现在,Text-to-SQL越来越重要了,所以今天就来聊聊Text-to-SQL。 Text-to-SQL是一种将自然语言查询转换为数据库查询的技术。它可以让用户通过自然语言来查询数据库,而不需要编写复杂的SQL语句。 T…...
【Linux】动静态库的制作与使用
一.对软硬链接的补充 1、无法对目录进行硬链接 为什么呢? 首先,我们在访问文件时,每一个文件都会有自己的dentry结构,这些结构会在内存中维护一棵路径树,来快速进行路径查找。但是如果某个节点直接使用硬链接到了根节…...
ubuntu22.04 如何安装 ch341 驱动
前言 本篇是介绍ubuntu22.04如何安装 ch341 驱动,并对其中遇到的问题进行整理。 一、流程 1.1 查看CH340驱动 首先是查看ubuntu22.04系统自带的驱动,用以下命令即可 ls /lib/modules/$(uname -r)/kernel/drivers/usb/serial 然后会跳出以下界面&…...
个人博客网站从搭建到上线教程
步骤1:设计个人网站 设计个人博客网站的风格样式,可以在各个模板网站上多浏览浏览,以便有更多设计网站风格样式的经验。 设计个人博客网站的内容,你希望你的网站包含哪些内容如你的个人基本信息介绍、你想分享的项目、你想分享的技术文档等等。 步骤2:选择开发技术栈 因…...
android 一步完成 aab 安装到手机
家人们谁懂!在 Android 系统安装 aab 应用超麻烦。满心期待快速体验,却发现 aab 无法直装,得先转为 apks 格式,这过程复杂易错。好不容易转好,还得安装 apks,一番折腾,时间与耐心全耗尽。别愁&a…...
c#使用forms实现屏幕截图
说明: c#使用forms实现屏幕截图 step1: 点击按钮,拖拽,截图,保存本地 C:\Users\wangrusheng\RiderProjects\WinFormsApp1\WinFormsApp1\Form1.cs using System; using System.Drawing; using System.Drawing.Imaging; using Syst…...
mac m4 Homebrew安装MySQL 8.0
1.使用Homebrew安装MySQL8 在终端中输入以下命令来安装MySQL8: brew install mysql8.0 安装完成后,您可以通过以下命令来验证MySQL是否已成功安装: 2.配置mysql环境变量 find / -name mysql 2>/dev/null #找到mysql的安装位置 cd /op…...
UE5学习笔记 FPS游戏制作26 UE中的UI
文章目录 几个概念创建一个UI蓝图添加UI获取UI的引用 切换设计器和UI蓝图将UI添加到游戏场景锚点轴点slotSizeToContent三种UI数据更新方式(Text、Image)函数绑定属性绑定事件绑定 九宫格分割图片按钮设置图片绑定按下事件 下拉框创建添加数据修改样式常用函数 滚动框创建添加数…...
Navicat导出mysql数据库表结构说明到excel、word,单表导出方式记录
目前只找到一张一张表导出的方式 使用information_schema传入表名查询 字段名根据需要自行删减,一般保留序号、字段名、类型、说明就行 SELECT COLUMNS.ORDINAL_POSITION AS 序号, COLUMNS.COLUMN_NAME AS 字段名, COLUMNS.COLUMN_TYPE AS 类型(长度), COLUMNS.N…...
目标检测 AP 计算 实例 python
以下是使用 Python 实现目标检测中 Average Precision (AP) 计算的完整实例,包含代码和注释。这里以 Pascal VOC 标准 为例(IoU阈值0.5)。 步骤1:准备数据 假设: gt_boxes: 真实标注框列表,格式为 …...
HarmonyOS NEXT图形渲染体系:重新定义移动端视觉体验
一、革命性架构设计 1.1 多线程并行渲染引擎 HarmonyOS NEXT通过四级流水线并行架构实现渲染效率质的飞跃,其核心包含: 优先级任务调度器:动态分配紧急渲染任务(如手势反馈)与常规任务智能线程池管理:根…...
使用 Docker 18 安装 Eureka:解决新版本 Docker 不支持的问题
使用 Docker 18 安装 Eureka:解决新版本 Docker 不支持的问题 在微服务架构中,Eureka 是一个常用的注册中心,用于服务发现和管理。然而,随着 Docker 版本的更新,一些新版本的 Docker 对 Eureka 的支持并不友好。如果你…...
Linux驱动开发 中断处理
目录 序言 1.中断的概念 2.如何使用中断 中断处理流程 中断上下文限制 屏蔽中断/使能 关键区别与选择 上半部中断 下半部中断 软中断(SoftIRQ) 小任务(Tasklet) 工作队列(Workqueue) 线程 IRQ(Threaded IRQ…...
Centos主机检查脚本
使用方法: 将脚本保存为 CentOS_syscheck.sh 添加执行权限: chmod x CentOS_syscheck.sh 执行脚本: ./CentOS_syscheck.sh #!/bin/bash# 设置颜色变量 RED\033[0;31m GREEN\033[0;32m YELLOW\033[0;33m BLUE\033[0;34m NC\033[0m # 重置…...
python系统之综合案例:用python打造智能诗词生成助手
不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。 python系列之综合案例 前言一、项目描述二、项目需求三、 项目实现1、开发准备2、代码实现 …...
【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解
目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…...
DeepSeek:巧用前沿AI技术,开启智能未来新篇章
引言 近年来,人工智能(AI)技术迅猛发展,大模型成为全球科技竞争的核心赛道。在这场AI革命中,DeepSeek作为中国领先的大模型研发团队,凭借其创新的技术架构、高效的训练方法和广泛的应用场景,迅…...
23种设计模式-结构型模式-桥接器
文章目录 简介问题解决方案示例总结 简介 桥接器是一种结构型设计模式,可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。 问题 假如你有一个几何形状Shape类,它有两个子类:圆形C…...
K8S学习之基础五十八:部署nexus服务
部署nexus服务 Nexus服务器是一个代码包管理的服务器,可以理解 Nexus 服务器是一个巨大的 Library 仓库。Nexus 可以支持管理的工具包括 Maven , npm 等,对于 JAVA 开发来说,只要用到 Maven 管理就可以了。Nexus服务器作用&#x…...
Docker Desktop 界面功能介绍
Docker Desktop 界面功能介绍 左侧导航栏 Containers(容器): 用于管理容器,包括查看运行中或已停止的容器,检查容器状态、日志,执行容器内命令,启动、停止、删除容器等操作。Images(镜像): 管理本地 Docker 镜像,可查看镜像列表、从 Docker Hub 拉取新镜像、删除镜…...
C++ set map
1.set和map是什么 set和map是 C STL 提供的容器,用于高效的查找数据,底层采用红黑树实现,其中set是Key模型,map是Key-Value模型 set和map的基本使用较为简单,这里不再叙述,直接进入实现环节 2.set和map的…...
Spring AI Alibaba 对话记忆使用
一、对话记忆 (ChatMemory)简介 1、对话记忆介绍 ”大模型的对话记忆”这一概念,根植于人工智能与自然语言处理领域,特别是针对具有深度学习能力的大型语言模型而言,它指的是模型在与用户进行交互式对话过程中,能够追踪、理解并利…...
Ubuntu24.04 离线安装 MySQL8.0.41
一、环境准备 1.1 官方下载MySQL8.0.41 完整包 1.2 上传包 & 解压 上传包名称是:mysql-server_8.0.41-1ubuntu24.04_amd64.deb-bundle.tar # 切换到上传目录 cd /home/MySQL8 # 解压: tar -xvf mysql-server_8.0.41-1ubuntu24.04_amd64.deb-bundl…...
SOME/IP-SD -- 协议英文原文讲解10
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.5 Non…...
Ubuntu上给AndroidStudio创建桌面图标
最近使用了Ubuntu开发了,默认的android studio没有桌面图标,还是很不方便,每次都要cd到bin目录启动studio.sh。 步骤1:cd /usr/share/applications linux系统里面,所有的应用启动入口都在 /usr/share/applications …...
