【知识科普】设计模式之-责任链模式
这里写自定义目录标题
- 概述
- 责任链模式的详细描述
- 责任链模式的使用场景
- 使用场景举例
- 1. 审批流程
- 示例:
- 2. 过滤器链
- 示例:
- 3. 事件处理系统
- 示例:
- 4. 插件系统
- 示例:
- Java代码示例及注释
- 代码解释
概述
责任链模式的详细描述
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照一定顺序处理请求,并且每个对象都有机会选择是否处理该请求或将其传递给下一个对象。这种模式将请求的发送者和接收者解耦,提供了更大的灵活性和可扩展性。
在责任链模式中,有两个主要角色:
- 抽象处理者(Handler):定义了处理请求的接口,并持有对下一个处理者的引用。
- 具体处理者(ConcreteHandler):实现了抽象处理者接口,负责实际处理请求的逻辑。
当一个请求从链首开始传递时,每个处理者都有机会处理该请求,直到其中一个处理者能够处理为止。如果当前处理者不能处理该请求,它会将请求传递给下一个处理者。这样,请求发送者无需知道具体的处理对象,只需将请求发送到责任链上即可。
责任链模式的使用场景
责任链模式通常用于以下场景:
- 多个对象可以处理同一请求:当系统中存在多个对象可以处理同一请求时,可以使用责任链模式将这些对象组织成一条链,并动态地选择处理者。
- 处理者之间的顺序不确定:当处理请求的对象之间的顺序不确定或需要动态调整时,责任链模式可以灵活地组织处理者的顺序。
- 请求处理具有多种可能性:当请求的处理结果有多种可能性,且这些可能性需要在运行时确定时,责任链模式可以根据请求的内容和当前处理者的逻辑来决定如何处理请求。
使用场景举例
责任链模式的使用场景通常涉及多个对象可以处理同一请求,且这些对象之间的处理顺序或责任分配可能在运行时动态变化的情况。以下是一些具体的使用场景示例:
1. 审批流程
在一个企业中,可能有多个层级的审批人员(如部门经理、总监、副总裁、总裁等)需要审批某个项目或请求。每个审批人员都有自己的审批权限和规则。使用责任链模式,可以将这些审批人员组织成一条链,当请求提交时,它会依次传递给每个审批人员,直到找到能够批准该请求的人员为止。
示例:
- 抽象审批者:定义了审批请求的方法。
- 具体审批者(如部门经理、总监等):实现了抽象审批者的方法,并根据自己的权限和规则决定是否批准请求或传递给下一个审批者。
2. 过滤器链
在Web开发中,经常需要对请求和响应进行过滤,如身份验证、日志记录、输入验证等。使用责任链模式,可以将这些过滤器组织成一条链,每个过滤器都有机会处理请求或响应,并在必要时将控制权传递给下一个过滤器。
示例:
- 抽象过滤器:定义了处理请求和响应的方法。
- 具体过滤器(如身份验证过滤器、日志记录过滤器等):实现了抽象过滤器的方法,并根据自己的逻辑处理请求或响应。
3. 事件处理系统
在一些应用程序中,可能需要处理各种类型的事件,如用户点击、键盘输入、系统错误等。使用责任链模式,可以将这些事件的处理程序组织成一条链,每个处理程序都有机会处理事件,并在必要时将事件传递给下一个处理程序。
示例:
- 抽象事件处理器:定义了处理事件的方法。
- 具体事件处理器(如用户点击处理器、键盘输入处理器等):实现了抽象事件处理器的方法,并根据事件类型和自己的逻辑处理事件。
4. 插件系统
在一些软件框架或平台中,可能允许用户或开发者添加自定义的插件来扩展功能。使用责任链模式,可以将这些插件组织成一条链,并在运行时动态地加载和调用它们。每个插件都有机会处理请求或提供自己的功能,并在必要时将控制权传递给下一个插件。
示例:
- 抽象插件:定义了插件需要实现的方法。
- 具体插件:实现了抽象插件的方法,并提供了自定义的功能或处理逻辑。
这些场景展示了责任链模式在动态责任分配、请求处理和事件处理方面的灵活性。通过组织成链式的处理者,责任链模式允许系统在运行时动态地决定由哪个对象处理请求,从而提高了系统的可扩展性和可维护性。
Java代码示例及注释
以下是一个使用Java实现责任链模式的示例代码,以及对应的注释:
// 定义请求类
class Request {private String content;public Request(String content) {this.content = content;}public String getContent() {return content;}
}// 定义抽象处理者接口
interface Handler {void handleRequest(Request request);
}// 具体处理者A,实现Handler接口
class ConcreteHandlerA implements Handler {private Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}@Overridepublic void handleRequest(Request request) {if (request.getContent().contains("A")) {System.out.println("ConcreteHandlerA: Handling the request");} else if (successor != null) {successor.handleRequest(request);}}
}// 具体处理者B,实现Handler接口
class ConcreteHandlerB implements Handler {private Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}@Overridepublic void handleRequest(Request request) {if (request.getContent().contains("B")) {System.out.println("ConcreteHandlerB: Handling the request");} else if (successor != null) {successor.handleRequest(request);}}
}// 客户端代码
public class Main {public static void main(String[] args) {// 创建处理者对象Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();// 设置处理者链handlerA.setSuccessor(handlerB);// 创建请求对象Request request1 = new Request("This is requestA");Request request2 = new Request("This is requestB");Request request3 = new Request("This is requestC");// 处理请求handlerA.handleRequest(request1); // ConcreteHandlerA: Handling the requesthandlerA.handleRequest(request2); // ConcreteHandlerB: Handling the requesthandlerA.handleRequest(request3); // 无输出,因为两个处理者都不处理requestC}
}
代码解释
- Request类:表示一个请求,包含请求的内容。
- Handler接口:定义了处理请求的接口,所有具体处理者都需要实现这个接口。
- ConcreteHandlerA和ConcreteHandlerB类:实现了Handler接口,分别处理包含"A"和"B"的请求内容。如果请求内容不匹配,它们会将请求传递给下一个处理者。
- Main类:客户端代码,创建处理者对象并设置处理者链,然后创建请求对象并调用处理请求的方法。
在这个示例中,当发送一个包含"A"的请求时,ConcreteHandlerA会处理该请求;当发送一个包含"B"的请求时,ConcreteHandlerB会处理该请求;如果发送一个包含"C"的请求,则两个处理者都不会处理该请求,因为没有处理者包含处理"C"的逻辑。
相关文章:
【知识科普】设计模式之-责任链模式
这里写自定义目录标题 概述责任链模式的详细描述责任链模式的使用场景 使用场景举例1. 审批流程示例:2. 过滤器链示例:3. 事件处理系统示例:4. 插件系统示例: Java代码示例及注释代码解释 概述 责任链模式的详细描述 责任链模式…...
fiddler安卓雷电模拟器配置踩坑篇
一、fiddler端配置 和网页版fiddler一样,需要首先再本机安装证书,可以参考我之前的fiddler浏览器配置文章,前期操作一致: 此处需要注意的是connections里面需要勾选allow remote这个选项,这个主要是为了后来再安卓模拟…...
机器学习5-多元线性回归
多元线性回归 主要了解多元线性回归的原理以及数学推导。 只有损失函数是凸函数才能确认是最优解,极值不一定是最优解 判定凸函数的方式非常多,其中一个方法是看黑塞矩阵是否是半正定的。 黑塞矩阵(hessian matrix)是由目标函数在…...
Linux kernel 堆溢出利用方法(三)
前言 本文我们通过我们的老朋友heap_bof来讲解Linux kernel中任意地址申请的其中一种比赛比较常用的利用手法modprobe_path(虽然在高版本内核已经不可用了但ctf比赛还是比较常用的)。在通过两道道近期比赛的赛题来讲解。 Arbitrary Address Allocation…...
对于GC方面,在使用Elasticsearch时要注意什么?
大家好,我是锋哥。今天分享关于【对于GC方面,在使用Elasticsearch时要注意什么?】面试题。希望对大家有帮助; 对于GC方面,在使用Elasticsearch时要注意什么? 1000道 互联网大厂Java工程师 精选面试题-Java…...
Xilinx PCIe高速接口入门实战(一)
引言:本文对Xilinx 7 Series Intergrated Block for PCI Express PCIe硬核IP进行简要介绍,主要包括7系列FPGA PCIe硬核资源支持、三IP硬核差异、PCIe硬核资源利用等相关内容。 1. 概述 1.1 7系列FPGA PCIe硬件资源支持 7系列FPGA对PCIe接口最大支持如…...
Flume 监控配置和实践
要解释 Flume 的监控机制,需要了解 Flume 是如何设计其监控架构的,以及如何将性能指标暴露给用户或集成工具。下面我将详细分解 Flume 的监控机制,从基础架构、实现原理到源码解析,并提供非专业人也能理解的通俗解释。 Flume 的监…...
深度学习基础1
目录 1. 深度学习的定义 2.神经网络 2.1. 感知神经网络 2.2 人工神经元 2.2.1 构建人工神经元 2.2.2 组成部分 2.2.3 数学表示 2.2.4 对比生物神经元 2.3 深入神经网络 2.3.1 基本结构 2.3.2 网络构建 2.3.3 全连接神经网络 3.神经网络的参数初始化 3.1 固定值初…...
《FPGA开发工具》专栏目录
《FPGA开发工具》专栏目录 1.Vivado开发 1.1使用相关 Vivado工程创建、仿真、下载与固化全流程 Vivado工程快速查看软件版本与器件型号 Vivado IP核的快速入门 官方手册和例程 Vivado中对已调用IP核的重命名 Vivado中增加源文件界面中各选项的解释 Vivado IP中Generate…...
李春葆《数据结构》-查找-课后习题代码题
一:设计一个折半查找算法,求查找到关键字为 k 的记录所需关键字的比较次数。假设 k 与 R[i].key 的比较得到 3 种情况,即 kR[i].key,k<R[i].key 或者 k>R[i].key,计为 1 次比较(在教材中讨论关键字比…...
【Git】:分支管理
目录 理解分支 创建分支 切换分支 合并分支 删除分支 合并冲突 分支管理策略 快进合并 正常合并 bug 分支 总结 理解分支 在版本控制系统中,分支是一条独立的开发线路。它允许开发者从一个主要的代码基线(例如master分支)分离出来…...
C、C++ 和 Java的区别
C、C 和 Java 是三种广泛使用的编程语言,它们各有特点,适合不同的应用场景。以下从多个角度对它们的区别进行分析: 基础特性 特性CCJava语言类型过程式编程语言过程式 面向对象编程语言纯面向对象编程语言(也支持过程式&#x…...
【Python-Open3D学习笔记】005Mesh相关方法
TriangleMesh相关方法 文章目录 TriangleMesh相关方法1. 查看mesh三角形面信息2. 可视化三角形3. 上采样4. 计算mesh形成的面积和体积 1. 查看mesh三角形面信息 def view_hull_triangles(hull: o3d.geometry.TriangleMesh):"""查看mesh三角形面信息(…...
js原型、原型链和继承
文章目录 一、原型1、prototype2、constructor 二、原型链1、字面量原型链2、字面量继承3、构造函数的原型链4、Object.create5、Object.setPrototypeOf 三、继承1、构造函数继承2、原型链继承3、组合继承 四、常见链条1、Function2、Object.prototype 继承是指将特性从父代传递…...
团队自创【国王的魔镜-2】
国王的魔镜-2 题目描述 国王有一个魔镜,可以把任何接触镜面的东西变成原来的两倍——只是,因为是镜子嘛,增加的那部分是反的。比如一条项链,我们用AB来表示,不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话&am…...
c++编程玩转物联网:使用芯片控制8个LED实现流水灯技术分享
在嵌入式系统中,有限的GPIO引脚往往限制了硬件扩展能力。74HC595N芯片是一种常用的移位寄存器,通过串行输入和并行输出扩展GPIO数量。本项目利用树莓派Pico开发板与74HC595N芯片,驱动8个LED实现流水灯效果。本文详细解析项目硬件连接、代码实…...
【Jenkins】docker 部署 Jenkins 踩坑笔记
文章目录 1. docker pull 超时2. 初始化找不到 initialAdminPassword 1. docker pull 超时 docker pull 命令拉不下来 docker pull jenkins/jenkins:lts-jdk17 Error response from daemon: Get "https://registry-1.docker.io/v2/": 编辑docker配置 sudo mkdir -…...
Unreal Engine使用Groom 打包后报错
Unreal Engine使用Groom打包后报错 版本5.4.4 blender 4.2.1 项目头发用了groom,运行后报错 错误: Assertion failed: Offset BytesToRead < UncompressedFileSize && Offset > 0 [File:E:\UnrealEngine-5.4.4-release\Engine\Source\R…...
嵌入式QT学习第3天:UI设计器的简单使用
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 Qt Creator 里自带的 Qt Designer,使用 Qt Designer 比较方便的构造 UI 界 面。 在 UI 文件添加一个按钮 左边找到 Push Button,然后拖拽到中…...
【连接池】.NET开源 ORM 框架 SqlSugar 系列
.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...
节能模式:OpenClaw+nanobot的间歇性任务调度技巧
节能模式:OpenClawnanobot的间歇性任务调度技巧 1. 为什么需要节能模式 去年夏天,我的电费账单突然飙升。排查后发现,那台24小时运行OpenClaw的工作站竟然是耗电大户——它持续调用着本地部署的Qwen大模型,GPU风扇昼夜不停地呼啸…...
如何高效访问优质内容?bypass-paywalls-chrome-clean工具全方位使用指南
如何高效访问优质内容?bypass-paywalls-chrome-clean工具全方位使用指南 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的数字时代,大量优质内容被…...
Windows虚拟控制器驱动完全指南:如何用ViGEmBus实现游戏设备模拟
Windows虚拟控制器驱动完全指南:如何用ViGEmBus实现游戏设备模拟 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾因游戏只支持特定手柄而…...
Unsloth Docker部署详解:从零开始搭建训练环境
Unsloth Docker部署详解:从零开始搭建训练环境 1. 环境准备与Docker安装 1.1 系统要求检查 在开始之前,请确保你的系统满足以下基本要求: 64位Linux系统(推荐Ubuntu 22.04)NVIDIA显卡驱动已安装(建议版…...
达摩院PALM春联模型多场景落地:政务大厅自助春联机解决方案
达摩院PALM春联模型多场景落地:政务大厅自助春联机解决方案 春节贴春联,是咱们中国人传承千年的文化习俗。一副好春联,不仅承载着对新年的美好祝愿,也体现着家庭的品味和格调。但你知道吗?现在写春联这件事࿰…...
别再折腾虚拟机了!用Docker 5分钟搞定Oracle 10g测试环境(附阿里云镜像源)
5分钟极速部署Oracle 10g:Docker化开发环境实战指南 每次需要搭建Oracle测试环境时,你是否也经历过这样的痛苦?下载几个GB的安装包、配置复杂的系统参数、等待漫长的安装过程,最后可能还会遇到各种依赖问题。作为一名长期与Oracle…...
从巨鲸到万物生长:Claude Code如何颠覆AI开发,带你从对话走向Agent平台搭建!
Claude Code凭借其六大核心能力,将AI开发带入全新阶段。通过CLAUDE.md实现项目记忆增强,Skills固化可复用工作流,Sub-Agent处理专业化任务,MCP连接外部服务,Plug-In打包完整解决方案。本文深入解析这些功能,…...
使用现代 Java 技术栈构建企业级 AI 应用
使用现代 Java 技术栈构建企业级 AI 应用 引言 随着人工智能技术的快速发展,企业级 AI 应用的需求也迅速增长。Java 作为一门成熟的企业级编程语言,其生态系统在 AI 应用开发中扮演着重要角色。本文将探讨如何利用 Java 技术栈构建生产级 AI 应用&#x…...
SGLang-v0.5.6实战体验:5种预装镜像,哪个最适合你的项目?
SGLang-v0.5.6实战体验:5种预装镜像,哪个最适合你的项目? 选型会上,技术负责人又抛出了那个经典问题:“我们到底用哪个环境来部署SGLang?” 会议室里立刻热闹起来。有人坚持用PyTorch 2.1,说它…...
英雄联盟智能辅助套件:重新定义MOBA游戏体验的开源工具集
英雄联盟智能辅助套件:重新定义MOBA游戏体验的开源工具集 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Tool…...
