行为模式10.职责链模式

行为型模式

  1. 模板方法模式(Template Method Pattern)
  2. 命令模式(Command Pattern)
  3. 迭代器模式(Iterator Pattern)
  4. 观察者模式(Observer Pattern)
  5. 中介者模式(Mediator Pattern)
  6. 备忘录模式(Memento Pattern)
  7. 解释器模式(Interpreter Pattern)
  8. 状态模式(State Pattern)
  9. 策略模式(Strategy Pattern)
  10. 职责链模式(Chain of Responsibility Pattern)
  11. 访问者模式(Visitor Pattern)

职责链模式(Chain of Responsibility Pattern)

职责链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在将请求的发送者和接收者解耦,通过多个处理对象串成一条链,每个对象都有机会处理这个请求,直到有一个对象处理它为止。也就是说,请求沿着链中的每个对象传递,直到有一个对象处理了它,或者链的末尾都没有对象处理这个请求。

主要思想
  • 将多个处理对象连接成一个链条:每个对象都持有对下一个处理对象的引用,并且每个对象可以决定是否处理请求,或者将请求传递给链上的下一个对象。
  • 解耦请求发送者和接收者:请求发送者不需要知道哪个对象最终会处理它,只需要传递给链条中的第一个对象,由链条内部决定如何分配请求。

1. 结构组成

职责链模式通常包含以下几个角色:

  • Handler(处理者):抽象处理者角色,定义处理请求的方法。如果能处理请求,则进行处理;否则,将请求传递给下一个处理者。
  • ConcreteHandler(具体处理者):每个具体处理者实现处理请求的逻辑,并决定是否将请求传递给下一个处理者。
  • Client(客户端):发送请求的角色,客户端将请求提交给职责链的第一个处理者。

2. 工作原理

职责链模式的工作原理通常如下:

  1. 客户端将请求提交给链上的第一个处理者。
  2. 第一个处理者判断自己是否能够处理该请求。如果能处理,就执行处理逻辑;如果不能处理,就将请求传递给链上的下一个处理者。
  3. 请求继续在链上被传递,直到有一个处理者处理该请求,或者链上的所有处理者都不能处理该请求。

下面是职责链模式的 Java 实现示例:

1. 定义 Handler(抽象处理者)

首先定义一个抽象的 Handler 类,这个类包含一个 setNext 方法用于设置下一个处理者,以及一个 handleRequest 方法用于处理请求。

abstract class Handler {protected Handler nextHandler; // 下一个处理者// 设置下一个处理者public void setNext(Handler nextHandler) {this.nextHandler = nextHandler;}// 处理请求的方法,子类需要实现具体的处理逻辑public abstract void handleRequest(String request);
}

2. 定义具体的处理者(ConcreteHandler)

接下来,我们创建具体的处理者类,每个处理者会根据请求的类型来决定是否处理该请求。如果不能处理,则传递给下一个处理者。

class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("ConcreteHandlerA 处理请求 A");} else if (nextHandler != null) {System.out.println("ConcreteHandlerA 无法处理请求 A,传递给下一个处理者");nextHandler.handleRequest(request);}}
}class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("ConcreteHandlerB 处理请求 B");} else if (nextHandler != null) {System.out.println("ConcreteHandlerB 无法处理请求 B,传递给下一个处理者");nextHandler.handleRequest(request);}}
}class ConcreteHandlerC extends Handler {@Overridepublic void handleRequest(String request) {if ("C".equals(request)) {System.out.println("ConcreteHandlerC 处理请求 C");} else if (nextHandler != null) {System.out.println("ConcreteHandlerC 无法处理请求 C,传递给下一个处理者");nextHandler.handleRequest(request);}}
}

3. 客户端代码(Client)

客户端代码负责构建处理链,并发送请求。

public class Client {public static void main(String[] args) {// 创建具体处理者Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();Handler handlerC = new ConcreteHandlerC();// 设置职责链,A -> B -> ChandlerA.setNext(handlerB);handlerB.setNext(handlerC);// 客户端请求System.out.println("客户端请求 A:");handlerA.handleRequest("A");System.out.println("\n客户端请求 B:");handlerA.handleRequest("B");System.out.println("\n客户端请求 C:");handlerA.handleRequest("C");System.out.println("\n客户端请求 D:");handlerA.handleRequest("D");}
}

6. 优缺点

优点:
  • 解耦请求发送者和接收者:客户端无需了解请求将由哪个具体处理者处理,只需要将请求发送到链上的第一个处理者,解耦了客户端与具体处理者之间的关系。
  • 责任分担:每个处理者只需要关心自己能处理的部分,不需要关心其他部分的实现。
  • 灵活的动态处理:可以动态地修改链的结构,例如在链中添加或移除处理者,或者调整处理者的顺序。
缺点:
  • 链的处理效率低:如果请求链很长,每个请求可能需要经过多个处理者才能被处理,影响性能。
  • 调试困难:由于请求在多个处理者之间传递,追踪请求的处理过程可能较为困难。
  • 处理顺序不容易管理:如果链上的处理者比较多,可能会出现某些处理者优先级问题,导致业务逻辑变得复杂。

7. 应用场景

职责链模式特别适合以下场景:

  • 请求的处理需要多个对象参与,而且这些对象的处理逻辑可能会变化或不固定。例如,权限校验、日志处理、审批流程等。
  • 多个对象可以处理同一个请求,并且具体处理的顺序不确定时,使用职责链可以灵活处理。
  • 需要避免请求和具体处理者之间的耦合,可以将不同的处理者通过职责链串联起来,降低系统耦合度。
典型应用:
  • UI事件处理:例如浏览器中的事件监听机制,多个事件监听器(如按钮点击、文本框输入等)通过事件链处理同一事件。
  • 审批流程:例如在公司审批流程中,员工提交的申请需要不同级别的管理人员进行审批,可以使用职责链模式来分级处理。
  • 日志处理:在多级日志系统中,可以根据日志级别逐步将日志传递给相应的处理器(如文件日志、数据库日志、控制台输出等)。

8. 总结

职责链模式通过将请求和处理逻辑分离,灵活地将多个处理对象连接成一个链。它的最大优势在于解耦了请求发送者和接收者,使得请求可以被链上的多个处理者灵活地处理。通过灵活配置链的结构,可以提高系统的扩展性和灵活性,但也可能增加调试和性能优化的难度。在实际开发中,职责链模式可以应用于事件处理、权限验证、审批流程等多个场景。

文中的示例代码在我的码云:https://gitee.com/ming-super/design-model.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503457.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Linux]Mysql9.0.1服务端脱机安装配置教程(redhat)

前言 本教程适用于在yum源不可用的LInux主机上安装Mysql的场景。 以redhat系主机做操作示例,debian系主机可参照步骤,将对应的rpm -ivh命令换成dpkg -i。 1. 官网下载安装包 https://dev.mysql.com/downloads/mysql/ 1.1 版本分类 MySQL Enterprise…

【JAVA】Java开发小游戏 - 简单的2D平台跳跃游戏 基本的2D平台跳跃游戏框架,适合初学者学习和理解Java游戏开发的基础概念

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默, 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把…

HTTP/HTTPS ②-Cookie || Session || HTTP报头

这里是Themberfue 上篇文章介绍了HTTP报头的首行信息 本篇我们将更进一步讲解HTTP报头键值对的含义~~~ ❤️❤️❤️❤️ 报头Header ✨再上一篇的学习中,我们了解了HTTP的报头主要是通过键值对的结构存储和表达信息的;我们已经了解了首行的HTTP方法和UR…

Spring Boot 项目自定义加解密实现配置文件的加密

在Spring Boot项目中, 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照: Spring Boot Jasypt 实现application.yml 属性加密的快速示例 但是作为一个技术强迫症,总是想着从底层开始实现属性的加解密,…

Bash Shell的操作环境

目录 1、路径与指令搜寻顺序 2、bash的进站(开机)与欢迎信息:/etc/issue,/etc/motd (1)/etc/issue (2)/etc/motd 3、bash的环境配置文件 (1)login与non-…

最好用的图文识别OCR -- PaddleOCR(2) 提高推理效率(PPOCR模型转ONNX模型进行推理)

在实际推理过程中,使用 PaddleOCR 模型时效率较慢,经测试每张图片的检测与识别平均耗时超过 5 秒,这在需要大规模自动化处理的场景中无法满足需求。为此,我尝试将 PaddleOCR 模型转换为 ONNX 格式进行推理,以提升效率。…

51单片机——共阴数码管实验

数码管中有8位数字,从右往左分别为LED1、LED2、...、LED8,如下图所示 如何实现点亮单个数字,用下图中的ABC来实现 P2.2管脚控制A,P2.3管脚控制B,P2.4管脚控制C //定义数码管位选管脚 sbit LSAP2^2; sbit LSBP2^3; s…

mv指令详解

🏝️专栏:https://blog.csdn.net/2301_81831423/category_12872319.html 🌅主页:猫咪-9527-CSDN博客 “欲穷千里目,更上一层楼。会当凌绝顶,一览众山小。” 目录 基本语法 主要功能 常用选项详解 1. …

css中的部分文字特性

文章目录 一、writing-mode二、word-break三、word-spacing;四、white-space五、省略 总结归纳常见文字特性,后续补充 一、writing-mode 默认horizontal-tbwriting-mode: vertical-lr; 从第一排开始竖着排,到底部再换第二排,文字与文字之间从…

【JMM】Java 内存模型

🥰🥰🥰来都来了,不妨点个关注叭! 👉博客主页:欢迎各位大佬!👈 文章目录 1. 前言2. JMM 内存模型内容3. JMM 内存模型简单执行示意图 ⚠️ 不要与 JVM 内存分布混为一谈论&#xff0c…

服务器等保测评审计日志功能开启(auditd)和时间校准

操作系统审计日志功能开启auditd CentOS 7 默认已经安装 auditd,如果没有,可以通过以下命令安装: yum install audit systemctl start auditd systemctl enable auditd配置审计规则 配置审计规则。添加所需的审计规则 永久规则文件&#xff1…

Backend - C# EF Core 执行迁移 Migrate

目录 一、创建Postgre数据库 二、安装包 (一)查看是否存在该安装包 (二)安装所需包 三、执行迁移命令 1. 作用 2. 操作位置 3. 执行(针对visual studio) 查看迁移功能的常用命令: 查看…

改进萤火虫算法之一:离散萤火虫算法(Discrete Firefly Algorithm, DFA)

离散萤火虫算法(Discrete Firefly Algorithm, DFA)是萤火虫算法的一种重要变种,专门用于解决离散优化问题。 一、基本概念 离散萤火虫算法将萤火虫算法的基本原理应用于离散空间,通过模拟萤火虫的闪烁行为来寻找全局最优解。在离散空间中,萤火虫的亮度代表解的优劣,较亮的…

Java SpringBoot使用EasyExcel导入导出Excel文件

点击下载《Java SpringBoot使用EasyExcel导入导出Excel文件(源代码)》 在 Java Spring Boot 项目中,导入(读取)和导出(写入) Excel 文件是一项常见的需求。EasyExcel 是阿里巴巴开源的一个用于简化 Java 环境下 Excel…

十年后LabVIEW编程知识是否会过时?

在考虑LabVIEW编程知识在未来十年内的有效性时,我们可以从几个角度进行分析: ​ 1. 技术发展与软件更新 随着技术的快速发展,许多编程工具和平台不断更新和改进,LabVIEW也不例外。十年后,可能会有新的编程语言或平台…

【Linux】文件的压缩与解压

目录 gzip和 gunzip bzip2 和 bunzip2(特点和gzip相似) xz和unxz(特点和gzip相似) zip 和 unzip tar gzip和 gunzip 特点:只能对单个的普通文件进行压缩 不能进行归档,压缩或解压后的源文件都不存在 压缩后所生成的压缩格式是.gz格式 压缩&…

touch详讲

🏝️专栏:https://blog.csdn.net/2301_81831423/category_12872319.html 🌅主页:猫咪-9527-CSDN博客 “欲穷千里目,更上一层楼。会当凌绝顶,一览众山小。” 目录 基本语法 主要功能 常用选项详解 1. …

【开源免费】基于Vue和SpringBoot的贸易行业crm系统(附论文)

本文项目编号 T 153 ,文末自助获取源码 \color{red}{T153,文末自助获取源码} T153,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

仓库叉车高科技安全辅助设备——AI防碰撞系统N2024G-2

在当今这个高效运作、安全第一的物流时代,仓库作为供应链的中心地带,其安全与效率直接关系到企业的命脉。 随着科技的飞速发展,传统叉车作业模式正逐步向智能化、安全化转型,而在这场技术革新中,AI防碰撞系统N2024G-2…