责任链模式(Chain of Responsibility)

责任链模式是一种行为设计模式,允许将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。

Chain-of-responsibility is a behavior design pattern that allows requests to be sent along the handler chain. 
After receiving the request, each handler can process it or pass it on to the next handler on the chain. 
Chain-of-responsibility pattern allows multiple objects to have the opportunity to process requests, 
thereby avoiding coupling between the sender and receiver of requests.  

结构设计

责任链会将特定行为转换为被称作处理者的独立对象。职责链模式建议将这些处理者连成一条链。链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。除了处理请求外,处理者还负责沿着链传递请求。请求会在链上移动,直至所有处理者都有机会对其进行处理。注意,处理者可以决定不再沿着链传递请求,这可高效地取消所有后续处理步骤。
责任链模式包含如下角色:
Handler是抽象处理者,声明了一个处理请求的接口,该接口通常仅包含单个方法用于请求处理,但有时还会包含一个设置后继者的方法。
ConcreteHandler是具体处理者,处理它所负责的请求,每个处理者接收到请求后,都必须决定是否进行处理,以及是否向下传递请求。可访问它的后继者,如果可处理该请求就处理,否则就将该请求转发给它的后继者。
处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
责任链模式类图表示如下:
请添加图片描述

伪代码实现

接下来将使用代码介绍下责任链模式的实现。

// 1、Handler是抽象处理者,声明了一个处理请求的接口,另外还包含一个设置后继者的方法
public abstract class Handler {
    private Handler nextHandler;

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    protected void doNext() {
        if (nextHandler != null) {
            nextHandler.handleRequest();
        }
    }

    public abstract void handleRequest();
}

// 2、具体处理者,处理它所负责的请求,接收到请求后,决定是否进行处理,以及是否向下传递请求
public class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest() {
        System.out.println("I am a concrete handler A instance");
        doNext();
    }
}
public class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest() {
        System.out.println("I am a concrete handler B instance");
        doNext();
    }
}

// 3、客户端
public class ResponsibilityClient {
    public void test() {
        // (1) 创建处理器实例
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        // (2) 定义先后顺序
        handlerA.setNextHandler(handlerB);
        // (3) 处理请求
        handlerA.handleRequest();
    }
}

适用场景

在以下情况下可以考虑使用责任链模式:
(1) 当必须按顺序执行多个处理者时, 可以使用该模式。无论以何种顺序将处理者连接成一条链,所有请求都会严格按照顺序通过链上的处理者。
(2) 当需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时,可以使用责任链模式。该模式能将多个处理者连接成一条链。
接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。这样所有处理者都有机会来处理请求。
(3) 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序。

优缺点

责任链模式有以下优点:
(1) 提高了灵活性。请求处理的顺序可以按需控制,提高了系统的灵活性。
(2) 符合开闭原则。可以在不更改现有代码的情况下在程序中新增处理者。
(3) 符合单一职责原则。发起操作和执行操作的类进行解耦。
但是该模式也存在以下缺点:
(1) 性能可能会受到影响。职责链的链路不宜过长,可能会引入性能问题。
(2) 不能保证请求一定被接收。因为没有指定处理者,所以存在请求直到链的末尾都得不到处理的情况。

参考

《设计模式 可复用面向对象软件的基础》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著, 李英军, 马晓星等译
https://refactoringguru.cn/design-patterns/chain-of-responsibility 责任链模式
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html 责任链模式
https://www.cnblogs.com/adamjwh/p/10932216.html 简说设计模式——职责链模式

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Activity启动过程详解(Android 12源码分析)

Activity的启动方式 启动一个Activity,通常有两种情况,一种是在应用内部启动Activity,另一种是Launcher启动 1、应用内启动 通过startActivity来启动Activity 启动流程: 一、Activity启动的发起 二、Activity的管理——ATMS 三、…

【AGC】付费下载上架下载后无法安装问题

【关键字】 AGC、付费下载、应用安装 【问题描述】 有开发者反馈用户下载后无法安装,采用未接入sdk,直接勾选付费-产品上架的方案,以前其他产品是能够正常安装的,现在不知道为啥。 报错信息:付费后显示“订单创建失…

Centos 从0搭建grafana和Prometheus 服务以及问题解决

下载 虚拟机下载 https://customerconnect.vmware.com/en/downloads/info/slug/desktop_end_user_computing/vmware_workstation_player/17_0 cenos 镜像下载 https://www.centos.org/download/ grafana 服务下载 https://grafana.com/grafana/download/7.4.0?platformlinux …

SpringBoot 2.1.7.RELEASE + Activiti 5.18.0 喂饭级练习手册

环境准备 win10 eclipse 2023-03 eclipse Activiti插件 Mysql 5.x Activiti的作用等不再赘叙&#xff0c;直接上代码和细节 POM <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>…

Matplotlib引领数据图表绘制

Matplotlib引领数据图表绘制 前言图像得组成画图设置 figure设置标题设置坐标轴设置 label 和 legend添加注释使用子图中文乱码解决保存图形显示图形条形图直方图散点图饼状图 总结 前言 在数据科学领域&#xff0c;数据可视化是一种强大的工具&#xff0c;能够将复杂的数据转…

华为推出手机系统云翻新服务:什么是云翻新?如何使用?

华为手机系统云翻新是华为推出的一项功能&#xff0c;旨在通过云服务提供系统翻新的服务。它可以帮助用户对手机的系统进行优化和更新&#xff0c;以提高手机的性能和流畅度。具体而言&#xff0c;华为手机系统云翻新功能提供了免费的云空间&#xff0c;用户可以将手机中的系统…

【C++笔记】C++启航之为C语言填坑的语法

【C笔记】C启航之为C语言填坑的语法 一、命名空间1、为什么要引入命名空间&#xff1f;2、命名空间的基本用法3、展开命名空间4、命名空间的套娃5、命名空间的自动合并 二、缺省参数1、为什么要引入缺省参数&#xff1f;2、缺省参数的基本用法3、缺省的参数必须从右向左4、缺省…

用Python批量复制文件,方法有9种,方便快捷

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 当我们复制一个文件时用复制粘贴就可以了&#xff0c;如果是多个文件呢&#xff1f; 就会很麻烦了&#xff01; 今天给大家介绍一下用Python批量复制文件&#xff0c;方法有九种&#xff01;希望对你有帮助 1. Shutil Copy…

【音视频】vms布署说明

目录 外场布署场景&#xff08;99%&#xff09; 研发实验场景&#xff08;1%&#xff09; 高级玩法 证书安装方法 外场布署场景&#xff08;99%&#xff09; 下面两种场景&#xff0c;为本产品主要应用场景&#xff0c;2023-08-08日后&#xff08;统一所有证书&#xff09;…

macOS下Django环境搭建-docker运行Django

1. macOS升级pip /Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip 2. 卸载Python3.9.5版本 $ sudo rm -rf /usr/local/bin/python3 $ sudo rm -rf /usr/local/bin/pip3 $ sudo rm -rf /Library/Frameworks/Python.framework 3. 安装P…

Vue3自定义简单的Swiper滑动组件-触控板滑动鼠标滑动左右箭头滑动-demo

代码实现了一个基本的滑动功能&#xff0c;通过鼠标按下、鼠标松开和鼠标移动事件来监听滑动操作。 具体实现逻辑如下&#xff1a; 在 onMounted 钩子函数中&#xff0c;我们为滚动容器添加了三个事件监听器&#xff1a;mousedown 事件&#xff1a;当鼠标按下时&#xff0c;设置…

TCP 三次握手,四次挥手

1、三次握手 第一次握手 SYN 等于1&#xff0c;SeqX 第二次握手 SYN等于1 ACK等于1&#xff0c;SeqY&#xff0c;AckX1 第三次SYN等于0 ACK等于1&#xff0c;SeqX1&#xff0c;AckY1 ackRow都是对应请求seqraw&#xff0c;三次握手后&#xff0c;Seq就是服务器前一个包中的ac…

Unity数字可视化学校_昼夜(三)

1、删除不需要的 UI using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class EnvControl : MonoBehaviour {//UIprivate Button btnTime;private Text txtTime; //材质public List<Material> matListnew Li…

解决word打字卡顿问题的方法

❤ 2023.8.5 ❤ 最近整理论文&#xff0c;本来我是wps死忠粉&#xff0c;奈何wps不支持latex公式。。。 无奈用起了word&#xff0c;但是谁想字数稍微多了一点&#xff0c;word就卡得欲仙欲死&#xff0c;打个字过去2s才显示出来&#xff0c;删除的时候都不知道自己删了几个字…

QGIS二次开发三:显示Shapefile

Shapefile 为 OGR 所支持的最重要的数据格式之一&#xff0c;自然可以被 QGIS 加载。那么该如何显示Shapefile呢&#xff1f; 一、先上代码 #include <qgsapplication.h> #include <qgsproviderregistry.h> #include <qgsmapcanvas.h> #include <qgsvec…

每天一道leetcode:剑指 Offer 50. 第一个只出现一次的字符(适合初学者)

今日份题目&#xff1a; 在字符串 s 中找出第一个只出现一次的字符。如果没有&#xff0c;返回一个单空格。 s 只包含小写字母。 示例1 输入&#xff1a;s "abaccdeff" 输出&#xff1a;b 示例2 输入&#xff1a;s "" 输出&#xff1a; 提示 0 …

MySQL流程控制(二十八)

二八佳人体似酥&#xff0c;腰悬利剑斩愚夫&#xff0c;虽然不见人头落,暗里教君骨髓枯。 上一章简单介绍了MySQL变量(二十七) ,如果没有看过,请观看上一章 一. 定义条件与处理程序 定义条件是事先定义程序执行过程中可能遇到的问题&#xff0c;处理程序定义了在遇到问题时应…

BIO,NIO,AIO总结

文章目录 1. BIO (Blocking I/O)1.1 传统 BIO1.2 伪异步 IO1.3 代码示例 1.4 总结2. NIO (New I/O)2.1 NIO 简介2.2 NIO的特性/NIO与IO区别1)Non-blocking IO&#xff08;非阻塞IO&#xff09;2)Buffer(缓冲区)3)Channel (通道)4)Selector (选择器) 2.3 NIO 读数据和写数据方式…

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接 背景目标依赖配置文件如下项目结构如下相关配置如下启动代码如下Controller如下启动成功接口调用成功 背景 工作做了一段时间&#xff0c;回忆起之前有个公司有线下笔试&#xff0c;要求考生做一个什么功能&#x…

无涯教程-Perl - fileno函数

描述 此函数返回指定的FILEHANDLE的文件描述符号(由C和POSIX函数使用)。通常,这仅在使用select函数和任何低级tty函数时才有用。 语法 以下是此函数的简单语法- fileno FILEHANDLE返回值 此函数返回FILEHANDLE的文件描述符(数字),失败时不确定。 Perl 中的 fileno函数 - 无…