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

【知识科普】设计模式之-责任链模式

这里写自定义目录标题

    • 概述
      • 责任链模式的详细描述
      • 责任链模式的使用场景
    • 使用场景举例
      • 1. 审批流程
      • 示例:
      • 2. 过滤器链
      • 示例:
      • 3. 事件处理系统
      • 示例:
      • 4. 插件系统
      • 示例:
    • Java代码示例及注释
      • 代码解释

概述

责任链模式的详细描述

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照一定顺序处理请求,并且每个对象都有机会选择是否处理该请求或将其传递给下一个对象。这种模式将请求的发送者和接收者解耦,提供了更大的灵活性和可扩展性。

在责任链模式中,有两个主要角色:

  1. 抽象处理者(Handler):定义了处理请求的接口,并持有对下一个处理者的引用。
  2. 具体处理者(ConcreteHandler):实现了抽象处理者接口,负责实际处理请求的逻辑。

当一个请求从链首开始传递时,每个处理者都有机会处理该请求,直到其中一个处理者能够处理为止。如果当前处理者不能处理该请求,它会将请求传递给下一个处理者。这样,请求发送者无需知道具体的处理对象,只需将请求发送到责任链上即可。

责任链模式的使用场景

责任链模式通常用于以下场景:

  1. 多个对象可以处理同一请求:当系统中存在多个对象可以处理同一请求时,可以使用责任链模式将这些对象组织成一条链,并动态地选择处理者。
  2. 处理者之间的顺序不确定:当处理请求的对象之间的顺序不确定或需要动态调整时,责任链模式可以灵活地组织处理者的顺序。
  3. 请求处理具有多种可能性:当请求的处理结果有多种可能性,且这些可能性需要在运行时确定时,责任链模式可以根据请求的内容和当前处理者的逻辑来决定如何处理请求。

使用场景举例

责任链模式的使用场景通常涉及多个对象可以处理同一请求,且这些对象之间的处理顺序或责任分配可能在运行时动态变化的情况。以下是一些具体的使用场景示例:

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}
}

代码解释

  1. Request类:表示一个请求,包含请求的内容。
  2. Handler接口:定义了处理请求的接口,所有具体处理者都需要实现这个接口。
  3. ConcreteHandlerA和ConcreteHandlerB类:实现了Handler接口,分别处理包含"A"和"B"的请求内容。如果请求内容不匹配,它们会将请求传递给下一个处理者。
  4. 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…...

李春葆《数据结构》-查找-课后习题代码题

一&#xff1a;设计一个折半查找算法&#xff0c;求查找到关键字为 k 的记录所需关键字的比较次数。假设 k 与 R[i].key 的比较得到 3 种情况&#xff0c;即 kR[i].key&#xff0c;k<R[i].key 或者 k>R[i].key&#xff0c;计为 1 次比较&#xff08;在教材中讨论关键字比…...

【Git】:分支管理

目录 理解分支 创建分支 切换分支 合并分支 删除分支 合并冲突 分支管理策略 快进合并 正常合并 bug 分支 总结 理解分支 在版本控制系统中&#xff0c;分支是一条独立的开发线路。它允许开发者从一个主要的代码基线&#xff08;例如master分支&#xff09;分离出来…...

C、C++ 和 Java的区别

C、C 和 Java 是三种广泛使用的编程语言&#xff0c;它们各有特点&#xff0c;适合不同的应用场景。以下从多个角度对它们的区别进行分析&#xff1a; 基础特性 特性CCJava语言类型过程式编程语言过程式 面向对象编程语言纯面向对象编程语言&#xff08;也支持过程式&#x…...

【Python-Open3D学习笔记】005Mesh相关方法

TriangleMesh相关方法 文章目录 TriangleMesh相关方法1. 查看mesh三角形面信息2. 可视化三角形3. 上采样4. 计算mesh形成的面积和体积 1. 查看mesh三角形面信息 def view_hull_triangles(hull: o3d.geometry.TriangleMesh):"""查看mesh三角形面信息&#xff08…...

js原型、原型链和继承

文章目录 一、原型1、prototype2、constructor 二、原型链1、字面量原型链2、字面量继承3、构造函数的原型链4、Object.create5、Object.setPrototypeOf 三、继承1、构造函数继承2、原型链继承3、组合继承 四、常见链条1、Function2、Object.prototype 继承是指将特性从父代传递…...

团队自创【国王的魔镜-2】

国王的魔镜-2 题目描述 国王有一个魔镜&#xff0c;可以把任何接触镜面的东西变成原来的两倍——只是&#xff0c;因为是镜子嘛&#xff0c;增加的那部分是反的。比如一条项链&#xff0c;我们用AB来表示&#xff0c;不同的字母表示不同颜色的珍珠。如果把B端接触镜面的话&am…...

c++编程玩转物联网:使用芯片控制8个LED实现流水灯技术分享

在嵌入式系统中&#xff0c;有限的GPIO引脚往往限制了硬件扩展能力。74HC595N芯片是一种常用的移位寄存器&#xff0c;通过串行输入和并行输出扩展GPIO数量。本项目利用树莓派Pico开发板与74HC595N芯片&#xff0c;驱动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&#xff0c;运行后报错 错误&#xff1a; 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&#xff0c;使用 Qt Designer 比较方便的构造 UI 界 面。 在 UI 文件添加一个按钮 左边找到 Push Button&#xff0c;然后拖拽到中…...

【连接池】.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 系列【数据事务…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...