设计模式之 责任链模式

devtools/2024/11/23 19:49:49/

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在将多个处理对象通过链式结构连接起来,形成一条处理请求的链条。每个处理对象都有机会处理请求,或者将请求传递给链中的下一个对象。这样,客户端不需要知道哪个具体的对象会处理请求,而是通过责任链的结构来自动地传递和处理请求。

责任链模式的核心思想是将处理请求的职责链式连接起来,由链中的对象依次处理请求,直到某个对象处理完请求为止。

一、责任链模式的组成部分

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

  1. Handler(处理者接口)

    定义了一个接口,声明了处理请求的方法。在该方法中,处理者通常会选择是否处理请求。如果能够处理,则处理请求,否则将请求转发给下一个处理者。
  2. ConcreteHandler(具体处理者)

    实现了Handler接口,定义了具体的处理逻辑。如果该对象能够处理请求,则直接处理;如果不能处理,则将请求传递给下一个处理者。
  3. Client(客户端)

    负责初始化责任链,并向链中的第一个处理者发送请求。客户端不需要关心请求是由哪一个处理者来完成的。
  4. Chain(责任链)

    由多个处理者对象组成。每个处理者对象都有一个指向下一个处理者的引用。请求会沿着责任链逐一传递,直到有处理者处理请求或者链的末尾。
二、责任链模式的工作原理

责任链模式的工作原理是将多个处理对象组成链条,每个处理对象知道下一个处理对象,并负责将请求转发给下一个对象。每个处理者对象会判断自己是否能够处理请求,如果可以处理请求,则执行相应的操作;如果不可以处理请求,则将请求转发给责任链中的下一个处理者。

这种设计模式非常适合处理多个处理条件之间的连贯流程,例如:请求审批流程、日志记录、事件处理等。

三、责任链模式的代码示例
  • 定义抽象处理者
    public abstract class Handler{protected Handler nextHandler;public abstract void setNext(Handler handler);public abstract void handleRequest(int request);
    }
  • 定义具体的处理者
    public class GroupHandler extends Handler{@Overridepublic void setNext(Handler handler) {nextHandler = handler;}@Overridepublic void handleRequest(int request) {if (request < 3){System.out.println("小组长批准"+request+"天假");}else {nextHandler.handleRequest(request);}}
    }
    
    public class Manager extends Handler{@Overridepublic void setNext(Handler handler) {nextHandler = handler;}@Overridepublic void handleRequest(int request) {if (request < 5){System.out.println("经理批准"+request+"天假");}else {nextHandler.handleRequest(request);}}
    }
    
    public class GeneralManager extends Handler{@Overridepublic void setNext(Handler handler) {throw new RuntimeException("总经理是最高职位");}@Overridepublic void handleRequest(int request) {if (request < 10){System.out.println("总经理批准"+request+"天假");}}
    }
    
  • 客户端代码
    public class Client {public static void main(String[] args) {GroupHandler groupHandler = new GroupHandler();Manager manager = new Manager();GeneralManager generalManager = new GeneralManager();groupHandler.setNext(manager);manager.setNext(generalManager);//请四天假groupHandler.handleRequest(4);}
    }
  • 运行结果
四、责任链模式的优缺点
优点:
  1. 解耦请求发送者与处理者:客户端不需要知道哪个处理者会处理请求,只需要发起请求即可,责任链的结构内部决定了请求的处理流程。
  2. 降低了对象之间的耦合度:每个处理者仅仅负责判断请求是否能处理,并将无法处理的请求传递给下一个处理者。这样,系统中的对象之间的依赖关系大大减少。
  3. 增强灵活性和扩展性:责任链中的每个处理者都可以独立扩展,可以通过增加新的处理者来修改或扩展请求处理的逻辑,而不需要修改现有的代码。
  4. 动态控制请求的处理流程:请求的处理可以动态改变,可以控制责任链的顺序,或者在运行时选择是否将请求传递给下一个处理者。
缺点:
  1. 性能开销:如果责任链较长,且每个请求都需要经过多个处理者,可能会导致性能问题,因为每个请求都需要被逐个检查和转发。
  2. 调试难度:由于请求可能会经过多个处理者,这种链式的调用可能会增加调试的难度,尤其是在请求的处理过程非常复杂时,调试和跟踪问题可能会变得更加困难。
  3. 请求处理不明确:如果没有明确的设计,责任链中的某个请求可能会一直传递下去,直到链的最后也没有处理,从而可能导致请求的处理不及时,或者被忽略。
五、责任链模式的应用场景

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

  1. 多层次的请求处理

    当有多个处理对象需要依次处理同一个请求时,责任链模式非常适用。例如,权限验证、审批流程等需要经过多个步骤的处理。
  2. 动态改变请求的处理顺序

    通过灵活配置责任链,可以动态改变请求的处理顺序,而无需修改客户端的代码。例如,在一些复杂的系统中,根据不同的配置,可能会根据不同的规则选择不同的处理链。
  3. 日志处理系统

    责任链模式非常适合用于日志系统,不同的日志处理器(如文件日志、数据库日志、网络日志等)可以按顺序处理日志请求。如果一个处理器无法处理日志,可以将其传递给下一个处理器。
  4. 事件处理系统

    在事件驱动的系统中,可以使用责任链模式来分发和处理事件。事件可以依次传递给多个处理者,每个处理者可以根据自己的条件决定是否处理该事件。
  5. 权限验证

    • 在系统中的权限控制过程中,可能会有多个权限验证步骤,责任链模式可以通过设置多个权限验证处理者来实现逐步验证,直到请求满足某个权限要求。

http://www.ppmy.cn/devtools/136365.html

相关文章

接口上传视频和oss直传视频到阿里云组件

接口视频上传 <template><div class"component-upload-video"><el-uploadclass"avatar-uploader":action"uploadImgUrl":on-progress"uploadVideoProcess":on-success"handleUploadSuccess":limit"lim…

Pytorch使用手册-Tensors(专题二)

这段代码是对 PyTorch 中张量(Tensors)的详细介绍和操作演示。以下是逐步讲解: 1. 什么是张量 (Tensor) 张量是一种专门的数据结构,与 NumPy 的多维数组(ndarray)类似: 它可以在 GPU 或其他硬件加速器上运行。张量可以与 NumPy 共享内存,避免不必要的数据拷贝。它是为…

基于 DRNN 神经网络整定的 PID 解耦控制

1. 基本原理 DRNN&#xff08;Dynamic Recurrent Neural Network, 动态递归神经网络&#xff09;是一种带有时间反馈的神经网络&#xff0c;能够建模系统的动态特性&#xff0c;适用于非线性、多变量、时变系统的控制。结合 PID 解耦控制&#xff0c;利用 DRNN 进行动态建模和…

VITE 忽略指定路径的资源

前言 问题起因是因为项目需要引入服务器端的网络图片 而在编写配置时发现&#xff0c;Vite并不支持排除指定前缀的资源 唯一可以排外的只有 Rollup 的 external 选项可以排除外部依赖&#xff0c;但他只能排除外部依赖&#xff0c;不支持指定路径资源或指定前缀的资源&#…

FreeRTOS信号量(一)

目录 什么是信号量&#xff1f; 1.信号量简介 2.二值信号量 2.1二值信号量简介 1. 首先&#xff0c;创建时&#xff0c;二值信号量默认无效 2. 之后中断释放信号量 3.信号量获取成功 4、任务再次进入阻塞态 2.2 创建二值信号量 1、函数vSemaphoreCreateBinary () 2、…

Python3.11.9+selenium,获取图片验证码以及输入验证码数字

Python3.11.9+selenium,获取图片验证码以及输入验证码数字 1、遇到问题:登录或修改密码需要验证码 2、解决办法: 2.1、安装ddddocr pip install ddddocr 2.2、解析验证码函数 import ddddocr def get_capcha_text():#获取验证码图片ele_pic = driver.find_element(By.XPAT…

FreeRTOS:事件标志组与任务通知

目录 一、事件标志组&#xff08;Event Groups&#xff09; 1、事件标志组的特点 2、事件标志组与队列、信号量的区别 3、关键API函数 4、示例代码 5、优缺点 6、总结 二、任务通知&#xff08;Task Notifications&#xff09; 1、任务通知的特点 2、关键API函数 3、…

MYSQL——数据更新

一、插入数据 1.插入完整的数据记录 在MYSQL中&#xff0c;使用SQL语句INSERT插入一条完整的记录&#xff0c;语法如下&#xff1a; INSERT INTO 表名 [(字段名1[,...字段名n])] VALUES (值1[...,值n]); 表名——用于指定要插入的数据的表名 字段名——用于指定需要插入数据…