Spring框架之责任链模式 (Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)详解

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在将请求的发送者和处理者解耦。它通过创建一条 处理请求的责任链,使得多个对象都有机会处理请求,从而避免了请求的发送者和处理者之间的紧耦合。责任链模式的核心思想是将请求沿着链传递,直到有一个对象处理它为止。

在责任链模式中,处理请求的对象(处理者)被组织成一个链条,链中的每个对象都负责对请求进行处理。如果当前对象不能处理请求,它将把请求传递给链中的下一个对象,直到请求被处理为止。

1. 责任链模式的定义

1.1 什么是责任链模式?

责任链模式通过将一系列的处理对象组成一条链,使得每个处理对象都有机会去处理请求。每个处理对象都包含指向下一个处理对象的引用,如果当前处理对象无法处理请求,它会将请求传递给链中的下一个对象,直到请求被某个处理对象处理为止。

1.2 责任链模式的关键思想
  • 解耦请求发送者和请求处理者:请求的发送者并不直接知道具体由哪个处理者来处理请求,而是通过一条链来传递请求。
  • 动态地调整请求的处理顺序:可以灵活地改变责任链中处理者的顺序,甚至可以动态地添加新的处理者。
  • 每个处理者只关心自己能处理的请求:如果某个处理者无法处理请求,它将把请求传递给链中的下一个处理者。

2. 责任链模式的结构

责任链模式通常由以下角色构成:

  1. Handler(处理者):定义了一个接口或抽象类,声明了处理请求的方法,并持有对下一个处理者的引用。
  2. ConcreteHandler(具体处理者):实现了 Handler 接口,并定义了如何处理请求。如果当前处理者不能处理请求,它会将请求传递给链中的下一个处理者。
  3. Client(客户端):负责创建链并将请求传递给责任链的第一个处理者。
类图
    +------------------+        |    Handler       |        +------------------+        | + handleRequest()|        | + setNextHandler()|        +------------------+        ^                    |                    +------------------------+   | ConcreteHandlerA       |  +------------------------+  | + handleRequest()      |  | + setNextHandler()     |  +------------------------+   ^                    |                    +------------------------+   | ConcreteHandlerB       |  +------------------------+  | + handleRequest()      |  | + setNextHandler()     |  +------------------------+   ^                    |                    +------------------------+   | ConcreteHandlerC       |  +------------------------+  | + handleRequest()      |  | + setNextHandler()     |  +------------------------+  

3. 责任链模式的实现

通过一个实际的例子来演示责任链模式的实现。假设我们有一个处理请求的系统,每个请求有一个不同的级别(如:低、中、高),我们希望根据请求的级别来选择处理它的处理者。

3.1 Java 示例代码
// 抽象处理者
abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(int level);
}// 具体处理者A
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(int level) {if (level <= 10) {System.out.println("ConcreteHandlerA处理请求,级别:" + level);} else if (nextHandler != null) {nextHandler.handleRequest(level); // 转发请求}}
}// 具体处理者B
class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(int level) {if (level <= 20) {System.out.println("ConcreteHandlerB处理请求,级别:" + level);} else if (nextHandler != null) {nextHandler.handleRequest(level); // 转发请求}}
}// 具体处理者C
class ConcreteHandlerC extends Handler {@Overridepublic void handleRequest(int level) {if (level <= 30) {System.out.println("ConcreteHandlerC处理请求,级别:" + level);} else if (nextHandler != null) {nextHandler.handleRequest(level); // 转发请求}}
}// 客户端代码
public class ChainOfResponsibilityPatternDemo {public static void main(String[] args) {// 创建责任链中的处理者Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();Handler handlerC = new ConcreteHandlerC();// 设置责任链handlerA.setNextHandler(handlerB);handlerB.setNextHandler(handlerC);// 客户端发出请求System.out.println("请求级别为10:");handlerA.handleRequest(10); // 由A处理System.out.println("\n请求级别为15:");handlerA.handleRequest(15); // 由B处理System.out.println("\n请求级别为25:");handlerA.handleRequest(25); // 由C处理System.out.println("\n请求级别为35:");handlerA.handleRequest(35); // 没有处理者能处理该请求}
}

输出结果

请求级别为10:
ConcreteHandlerA处理请求,级别:10请求级别为15:
ConcreteHandlerB处理请求,级别:15请求级别为25:
ConcreteHandlerC处理请求,级别:25请求级别为35:
(无输出)
3.2 解释
  • ConcreteHandlerA 只能处理请求级别小于或等于 10 的请求。如果请求级别大于 10,它会将请求转发给 ConcreteHandlerB 处理。
  • ConcreteHandlerB 只能处理请求级别小于或等于 20 的请求,超过这个级别的请求会被转发给 ConcreteHandlerC
  • ConcreteHandlerC 只能处理请求级别小于或等于 30 的请求。
  • 如果请求级别超过 30,责任链中没有任何处理者可以处理此请求,系统将不会输出任何内容。

4. 责任链模式的应用场景

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

  1. 多个对象可以处理一个请求:当一个请求可以由多个对象中的任何一个对象来处理时,可以使用责任链模式来处理。例如:请求的处理依赖于请求的级别或类型。
  2. 请求处理者的顺序不确定:当请求处理的顺序可以灵活变化时,可以使用责任链模式。例如:日志记录系统中的不同日志级别处理器,日志处理器可以按优先级顺序链式连接。
  3. 请求的处理者不一定知道最终的处理者是谁:责任链模式通过将请求沿链传递,避免了请求发送者和处理者之间的紧耦合。
  4. 动态地为请求分配处理者:通过责任链模式,可以动态地改变请求的处理顺序,甚至添加新的处理者。

5. 责任链模式的优缺点

5.1 优点
  • 降低耦合度:请求的发送者不需要知道哪个具体对象会处理请求,只需要知道责任链的起始处理者即可。这使得发送者和处理者之间的耦合度较低。
  • 增强灵活性:通过改变责任链的顺序,可以灵活地调整请求处理的方式,而无需修改请求的发送者或处理者。
  • 可扩展性强:责任链模式可以轻松地扩展新的处理者,只需将新的处理者添加到链中即可。
5.2 缺点
  • 可能导致请求得不到处理:如果责任链中的每个处理者都不能处理请求,那么请求就会一直在链中传递,直到超出链的范围。此时,客户端就无法获得处理结果。
  • 调试难度较大:由于请求会沿着链传递,可能会导致请求的跟踪变得较为困难,尤其是在责任链很长的情况下。

6. 责任链模式的实际应用

责任链模式广泛应用于实际项目中,特别是在处理一系列操作或任务时,以下是一些常见的应用场景:

  1. 日志处理系统:不同的日志记录器根据日志级别(如 DEBUG、INFO、ERROR)进行处理,日志处理器通常是责任链模式的一个典型应用。
  2. 审批流程:例如在企业的工作流系统中,某些任务可能需要多级审批,责任链模式可以非常自然地实现不同级别的审批处理。
  3. 事件处理系统:在 GUI 事件处理中,事件可以在多个事件监听器之间传递,直到某个监听器处理完该事件为止。
  4. 命令处理系统:例如,HTTP 请求处理中的路由系统,可以将请求传递给不同的处理器,根据请求的类型选择合适的处理逻辑。

7. 总结

责任链模式是一种行为型设计模式,通过将请求沿链传递,直到有一个对象处理它为止。它的主要优点是降低了请求发送者与处理者之间的耦合度,增强了系统的灵活性和可扩展性。然而,责任链模式也存在请求无法得到处理的风险以及调试上的难度。在适当的场景下,责任链模式可以有效地提高系统的设计灵活性和可维护性。

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

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

相关文章

游戏引擎学习第八天

视频参考: https://www.bilibili.com/video/BV1ouUPYAErK/ 理解下面的代码 关于虚函数 代码分解 结构体 foo 的定义&#xff1a; struct foo {int32 X;int64 Y;virtual void Bar(int c); };foo 结构体有两个成员变量&#xff1a;X&#xff08;int32 类型&#xff09;和 Y&…

工业通信协议对比:OPC-UA、Modbus、MQTT、HTTP

综合对比表 对比项OPC-UAModbusMQTTHTTP通信效率低&#xff0c;带宽消耗高高高&#xff0c;开销低&#xff0c;效率高低&#xff0c;带宽消耗大实时性一般&#xff0c;延迟较高高&#xff0c;延迟低高&#xff0c;低延迟低&#xff0c;延迟高性能消耗高&#xff0c;需要高性能…

Xcode 16 使用 pod 命令报错解决方案

原文请点击这个跳转 一、问题现象&#xff1a; 有人会遇到 Xcode 升级到 16 后&#xff0c;新建应用然后使用 pod init 命令会报错如下&#xff1a; Stack Ruby : ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-darwin23]RubyGems : 3.5.22Host : macOS 15.0 (24A335…

概率论之正态分布密度函数与matlab

文章目录 0.浅谈我的想法1.正态分布引入1.1公式和对应概率1.2模拟生成数据1.3图像绘制1.4图像的调整1.5概率密度函数1.6两个方式的对比分析1.7分布函数1.8分位数效果展示 0.浅谈我的想法 众所周知&#xff0c;在这个数学建模的这个过程之中会遇到很多的这个概率论的相关的问题…

【maven踩坑】一个坑 junit报错 但真正导致这个的不是junit的原因

目录 事件起因环境和工具操作过程解决办法结束语 事件起因 报错一&#xff1a; Internal Error occurred. org.junit.platform.commons.JUnitException: TestEngine with ID junit-vintage failed to discover tests报错二&#xff1a; Internal Error occurred. org.junit.pl…

【算法】——二分查找合集

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 零&#xff1a;二分查找工具 1&#xff1a;最基础模版 2&#xff1a;mid落点问题 一&#xff1a;最…

caozha-CEPCS(新冠肺炎疫情防控系统)

caozha-CEPCS&#xff0c;是一个基于PHP开发的新冠肺炎疫情防控系统&#xff0c;CEPCS&#xff08;全称&#xff1a;COVID-19 Epidemic Prevention and Control System&#xff09;&#xff0c;可以应用于单位、企业、学校、工业园区、村落等等。小小系统&#xff0c;希望能为大…

AI技术赋能电商行业:创新应用与未来展望

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐步渗透到各行各业&a…

若依项目-结构解读

项目结构 admin模块 common模块 framework模块 service模块 配置 依赖关系 前端接口 src 表结构

音视频入门基础:MPEG2-TS专题(3)——TS Header简介

注&#xff1a;本文有部分内容引用了维基百科&#xff1a;https://zh.wikipedia.org/wiki/MPEG2-TS 一、引言 本文对MPEG2-TS格式的TS Header进行简介。 进行简介之前&#xff0c;请各位先下载MPEG2-TS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-TS的官方文档。但是ITU提供的…

RN开发遇到的坑

1 、 RN 启动崩溃 https://blog.csdn.net/qq_31915745/article/details/108125671 2、修改报红⻚ https://blog.csdn.net/weixin_43969056/article/details/104757926 3 、编译不过去提示 glog-0.3.5 有问题&#xff0c; 找到 / 项⽬ /node_modules/react-native/scripts/ io…

折叠手机失败了,有手机品牌宣布退出,苹果成为赢家

日前一家手机企业宣布停止研发大折叠手机&#xff0c;这对于国产手机来说显然是一大打击&#xff0c;他们都希望以折叠手机抢占高端手机市场&#xff0c;然而残酷的市场现实却是消费者始终难以接受折叠手机&#xff0c;导致折叠手机的销量规模始终难以扩大。 折叠手机最早由三星…

解决Jenkins使用 Git 参数插件拉取 commit 列表缓慢问题

Jenkins使用 Git 参数插件拉取 commit 列表缓慢问题 项目问题问题描述解决方案具体实现 项目问题 在 Jenkins 中使用 Git 参数插件 进行参数化构建&#xff0c;具有多方面的重要性和好处。这不仅提高了构建的灵活性和透明度&#xff0c;还能大大提升开发和运维效率。以下是使用…

Python数据分析NumPy和pandas(二十七、数据可视化 matplotlib API 入门)

数据可视化或者数据绘图是数据分析中最重要的任务之一&#xff0c;是数据探索过程的一部分&#xff0c;数据可视化可以帮助我们识别异常值、识别出需要的数据转换以及为模型生成提供思考依据。对于Web开发人员&#xff0c;构建基于Web的数据可视化显示也是一种重要的方式。Pyth…

sqli—labs靶场 5-8关 (每日4关练习)持续更新!!!

Less-5 上来先进行查看是否有注入点&#xff0c;判断闭合方式&#xff0c;查询数据列数&#xff0c;用union联合注入查看回显位&#xff0c;发现到这一步的时候&#xff0c;和前四道题不太一样了&#xff0c;竟然没有回显位&#xff1f;&#xff1f;&#xff1f; 我们看一下源…

从建立TRUST到实现FAIR:可持续海洋经济的数据管理

1. 引言 随着我们对信息管理方式的信任&#xff0c;我们的社会对数字化数据的以来呈指数级增长。为了跟上大数据的需求&#xff0c;通过不断的努力和持续实践&#xff0c;对“good”数据管理方式的共识也在不断发展和演变。 加拿大正在建设国家基础设施和服务以及研究数据管理…

基于GPS/GIS数据融合与预处理技术的工厂导航系统(三)

在智能制造与智慧物流的背景下&#xff0c;厂区导航系统的高效性与准确性至关重要。然而&#xff0c;GPS信号易受环境干扰&#xff0c;GIS数据则可能因来源多样而存在误差。本文旨在通过详细剖析GPS数据的获取、解析与误差校正&#xff0c;GIS数据的导入、图层管理与空间数据清…

【微服务设计】从理论到实践:2PC(两阶段提交)与SAGA的全面比较与示例

在现代分布式系统中&#xff0c;事务一致性是一个重要的挑战。为了解决这一问题&#xff0c;业界提出了多种事务处理协议&#xff0c;其中两阶段提交&#xff08;2PC&#xff09;和SAGA是两种常见的方法。本文将详细介绍这两种协议的原理、应用场景及其优缺点&#xff0c;并通过…

Django 外键引用另一个表中的多个字段

在 Django 中&#xff0c;外键&#xff08;ForeignKey&#xff09;通常只引用另一张表的一个字段&#xff0c;比如一个主键或一个唯一标识字段。然而&#xff0c;如果我们需要让一个外键引用另一张表中的多个字段&#xff0c;通常有以下几种方法来实现这种关系。 1、问题背景 …

通俗易懂:@Configuration 和 @Component 注解的区别

文章目录 Component&#xff1a;通用的组件注解什么情况下用 Component&#xff1f;注意&#xff1a; Configuration&#xff1a;专门用来定义配置的类为什么使用 Configuration&#xff1f; Configuration 和 Component 的区别举个例子 总结推荐阅读文章 在 Spring 中&#xf…