设计模式|责任链模式(Chain of Responsibility Pattern)
文章目录
- 结构
- 优点
- 缺点
- 使用责任链的步骤
- 示例
- 有哪些知名框架采用了责任链模式
- 责任链模式和链表有什么关联
- 常见面试题
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你创建一个对象链。请求将沿着这个链传递,直到有一个对象处理它为止。这种模式可以使请求的发送者和接收者解耦。
当想让一个以上的对象有机会能够处理同一请求的时候,就可以使用责任链模式(Chanin of Responsibility Pattem)
结构
- 抽象处理者(Handler):定义了一个处理请求的接口。通常包含一个指向下一个处理者的引用。
- 具体处理者(Concrete Handler):实现了处理请求的具体逻辑。如果能够处理请求,就处理之;否则将请求传递给下一个处理者。
优点
- 解耦了请求发送者和接收者,增强了系统的灵活性。
- 可以动态地增加或修改处理者。
- 简化了对象,每个具体处理者只需关注自己的业务逻辑。
缺点
- 请求的处理可能会传递到链的末端仍未被处理。
- 可能会影响性能,特别是在链较长时。
- 如果链设置不当,可能会导致循环引用。
使用责任链的步骤
为请求创建一个对象链,每个对象依次检查此请求,并对其进行处理,或者将其传递给链中的下一个对象;
链中的每一个对象都需要扮演一个处理器,并且有一个后继对象,如果他可以处理请求,就进行处理,如果不能,就将请求转发给后继者
示例
考虑一个简单的审批流程,包括经理、部门主管和CEO三个级别的审批。在这个场景中,责任链模式可以很好地应用。
// 抽象处理者
abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(String request);
}// 具体处理者1
class Manager extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("manager")) {System.out.println("Manager approved the request.");} else {System.out.println("Manager cannot handle the request.");if (successor != null) {successor.handleRequest(request);}}}
}// 具体处理者2
class DepartmentHead extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("department_head")) {System.out.println("Department Head approved the request.");} else {System.out.println("Department Head cannot handle the request.");if (successor != null) {successor.handleRequest(request);}}}
}// 具体处理者3
class CEO extends Handler {@Overridepublic void handleRequest(String request) {if (request.equals("CEO")) {System.out.println("CEO approved the request.");} else {System.out.println("CEO cannot handle the request.");if (successor != null) {successor.handleRequest(request);}}}
}// 客户端
public class Main {public static void main(String[] args) {// 创建具体处理者对象Handler manager = new Manager();Handler departmentHead = new DepartmentHead();Handler ceo = new CEO();// 设置责任链manager.setSuccessor(departmentHead);departmentHead.setSuccessor(ceo);// 发送请求manager.handleRequest("department_head");manager.handleRequest("manager");manager.handleRequest("CEO");manager.handleRequest("other");}
}
在这个示例中,**Handler**是抽象处理者,包含了一个指向下一个处理者的引用。 **Manager**、 DepartmentHead和CEO是具体的处理者,它们实现了handleRequest`方法来处理请求。在客户端代码中,首先创建具体处理者对象,然后设置责任链,并发送请求。
有哪些知名框架采用了责任链模式
责任链模式在许多知名的框架和库中都有应用。以下是一些采用责任链模式的知名框架和库的例子:
- Java Servlet 中的 Filter Chain:Java Servlet 中的过滤器(Filter)是一个典型的责任链模式的实现。多个过滤器按照顺序组成一个链,每个过滤器都有机会处理请求,或将请求传递给下一个过滤器。
- Spring 框架中的拦截器(Interceptor):Spring 框架中的拦截器也是一种责任链模式的应用。拦截器可以在控制器方法执行之前或之后执行特定的逻辑,多个拦截器按照配置顺序形成一个链。
- Node.js 中的 Connect 和 Express 框架:Connect 和 Express 框架中的中间件(Middleware)也采用了责任链模式的思想。多个中间件按照顺序组成一个链,每个中间件都有机会处理请求,或将请求传递给下一个中间件。
- .NET Core 中的中间件:在 .NET Core 中,使用中间件来处理 HTTP 请求。类似于 Node.js 中的中间件,中间件按照顺序形成一个链,每个中间件都有机会处理请求,或将请求传递给下一个中间件。
- Android 中的事件传递机制:在 Android 中,事件传递机制也可以看作是责任链模式的一种应用。当用户触摸屏幕时,事件首先传递给顶层的 View,然后逐级向下传递,直到某个 View 处理了事件为止。
这些是一些采用责任链模式的知名框架和库的例子,它们充分利用了责任链模式的灵活性和可扩展性,使得代码更加模块化和易于维护。
责任链模式和链表有什么关联
责任链模式和链表之间有一些相似之处,主要体现在它们的结构特点和数据流动方式上。具体来说,它们的关联在于:
- 链式结构:
- 责任链模式中的处理者对象按照一定的顺序连接成链,每个处理者都持有对下一个处理者的引用。这种结构类似于链表中节点之间的链接。
- 链表也是一种链式结构,由节点组成,每个节点包含对下一个节点的引用。
- 数据流动:
- 在责任链模式中,请求沿着责任链流动,每个处理者都有机会处理请求或将请求传递给下一个处理者。这种数据的传递和处理方式类似于链表中数据元素的遍历。
- 链表中的数据元素通过节点之间的引用进行流动和访问,可以顺序地遍历整个链表。
虽然责任链模式和链表在结构上有相似之处,并且都涉及到数据的顺序流动,但它们的目的和应用场景不同。责任链模式用于实现请求的传递和处理,而链表用于组织和存储数据。因此,虽然有关联,但它们在概念上和实际应用中的作用是不同的。
常见面试题
在面试中,关于责任链模式的问题可能涉及其原理、优缺点、应用场景以及实际应用等方面。以下是一些可能的问题以及相应的答案:
- 责任链模式的原理是什么?
答案: 责任链模式是一种行为设计模式,其中多个对象按照顺序组成链,每个对象都有机会处理请求或将请求传递给下一个对象。请求在链上传递,直到被处理或者达到链的末端。 - 责任链模式的优点有哪些?
答案:
- 解耦了请求发送者和接收者,增强了系统的灵活性和可维护性。
- 可以动态地增加或修改处理者,无需修改客户端代码。
- 简化了对象,每个具体处理者只需关注自己的业务逻辑。
- 责任链模式的缺点是什么?
答案:
- 可能会导致请求的处理延迟,特别是在链较长时。
- 如果责任链设置不当,可能会导致请求无法被处理或形成循环引用。
- 请求可能会到达链的末端仍未被处理。
- 责任链模式在什么情况下适用?
答案:
- 当有多个对象可以处理同一请求,但具体处理者未知时。
- 当需要在运行时动态确定处理请求的对象时。
- 当想要将请求的发送者和接收者解耦时。
- 能否举例说明一个实际应用场景中如何使用责任链模式?
答案: 例如,在一个在线购物系统中,可以应用责任链模式来处理退款请求。不同级别的管理人员可以处理不同金额范围的退款请求,如普通员工可以处理小额退款,主管可以处理中额退款,高级管理人员可以处理大额退款。当有退款请求时,系统首先将请求发送给普通员工,如果金额超出其处理范围,则将请求传递给主管,以此类推,直到有人处理请求或者到达责任链的末端。
相关文章:
设计模式|责任链模式(Chain of Responsibility Pattern)
文章目录 结构优点缺点使用责任链的步骤示例有哪些知名框架采用了责任链模式责任链模式和链表有什么关联常见面试题 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你创建一个对象链。请求将沿着这个链传递ÿ…...
文件服务器之二:SAMBA服务器
文章目录 什么是SAMBASAMBA的发展历史与名称的由来SAMBA常见的应用 SAMBA服务器基础配置配置共享资源Windows挂载共享Linux挂载共享 什么是SAMBA 下图来自百度百科 SAMBA的发展历史与名称的由来 Samba是一款开源的文件共享软件,它基于SMB(Server Messa…...
20.安全性测试与评估
每年都会涉及;可能会考大题;多记!!! 典型考点:sql注入、xss; 从2个方面记: 1、测试对象的功能、性能; 2、相关设备的工作原理; 如防火墙,要了解防…...
阿里巴巴实习面经
本人bg:浙江大学,计算机研二,本科也是浙大计算机专业的。 在阿里巴巴达摩院实习,算法岗,我是去年拿到的阿里巴巴达摩院的实习offer,这个过程还是比较惊心动魄,所以我称之为惊心动魄版本…...
javaweb学习(day11-监听器Listener过滤器Filter)
一、监听器Listener 1 Listener介绍 Listener 监听器它是 JavaWeb 的三大组件之一。JavaWeb 的三大组件分别是:Servlet 程 序、Listener 监听器、Filter 过滤器 Listener 是 JavaEE 的规范,就是接口 监听器的作用是,监听某种变化(一般就是对…...
教你快速认识Java中的抽象类和接口
目录 引言 抽象类(Abstract Class) 抽象类的概念 抽象类的图标 抽象类的语法 抽象类的特点 接口(Interface) 接口的概念 接口的图标 接口的语法 接口的特点 接口的使用 接口的意义 抽象类与接口的区别 Object类 结…...
Linux第5课 Linux目录介绍
文章目录 Linux第5课 Linux目录介绍一、打开系统目录二、查看系统目录 Linux第5课 Linux目录介绍 系统目录就是指操作系统的主要文件存放的目录,目录中的文件直接影响到系统是否正常工作,了解这些目录的功能,对使用系统会有很大的帮助。 一…...
GitHub要求2FA?不慌,有它(神锁离线版)帮你!
GitHub宣布,到 2023 年底,所有用户都必须要启用双因素身份验证 (2FA),不能只用密码啦。 说实话,听到这消息小编是非常高兴的。 正如GitHub的首席安全官Mike Hanley所说,软件供应链是从开发者开始的,保护开…...
C语言第四十弹---预处理(下)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 预处理 1、#和## 1.1 #运算符 1.2、##运算符 2、命名约定 3、#undef 4、命令行定义 5、条件编译 6、头文件的包含 6.1、头文件被包含的方式 6.1.1、本地…...
SYS-2722音频分析仪SYS2722
181/2461/8938产品概述: Audio Precision 2722 音频分析仪是 Audio Precision 屡获殊荣的 PC 控制音频分析仪的旗舰型号,长期以来一直是音频设备设计和测试的全球公认标准。功能齐全的 SYS-2722 提供了测试转换器技术最新进展所需的无与伦比的失真和噪声…...
下载页面上的视频
引言:有些页面上的视频可以直接右键另存为或者F12检索元素找到视频地址打开后保存,但有些视频页面是转码后的视频,不能直接另存为视频格式,可以参考下本方法 以该页面视频为例:加载中...点击查看详情https://wx.vzan.c…...
静态路由协议实验综合实验
需求: 1、除R5的换回地址已固定外,整个其他所有的网段基于192.168.1.0/24进行合理的IP地址划分。 2、R1-R4每台路由器存在两个环回接口,用于模拟连接PC的网段;地址也在192.168.1.0/24这个网络范围内。 3、R1-R4上不能直接编写到…...
qt MVC软件设计模式
在Qt中使用MVC(Model-View-Controller)软件设计模式可以帮助你将数据模型、用户界面和控制逻辑有效地分离,从而使得代码更清晰,更易于维护和扩展。以下是在Qt中使用MVC模式的一般思路: Model(模型ÿ…...
代码随想录刷题随记15-二叉树回溯
代码随想录刷题随记15-二叉树回溯 110.平衡二叉树 leetcode链接 一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 求深度和求高度的区别: 求深度可以从上到下去查 所以需要前序遍历(中左右ÿ…...
基于SpringBoot Vue养老院管理
一、📝功能介绍 基于SpringBoot Vue养老院管理 角色:管理员、企业、老人子女、老人 管理员:管理员登录进入养老院管理系统可以对系统首页、个人中心、服务人员管理、老人管理、老人子女管理、老人档案管理、社区活动管理、活动记录管理、床…...
盘点编程方法论中的一些思想
背景 在日常编程开发中,虽然不同公司,业务不同,语言不同,但是工作久了,我们会发现一些编程思想几乎是不变的。这些编程思想,往往来自于大量实际问题场景的方法总结,可以很好的应对某一类问题。如…...
通过电机转速计算主轴旋转单圈所需时间(CODESYS ST代码)
1、伺服丝杠系统常用算法功能块 伺服丝杠系统常用算法功能块-CSDN博客文章浏览阅读353次。这篇博客主要介绍伺服、丝杠系统常用的运算功能块,其它相关运算可以查看下面文章链接:信捷PLC脉冲频率、位移、转速相关计算(C语言编程应用)_RXXW_Dor的博客-CSDN博客。https://rxxw-…...
多线程的入门(二)线程实现与初步使用
1.实现Runable接口 实现Runable接口,实现run方法; 这种方式创建的线程实现类执行时需要创建Thread实例去运行该任务 示例如下: package com.example.springbootdamo.Thread;import org.apache.logging.log4j.LogManager; import org.apach…...
数据结构(初阶)第二节:顺序表
数据结构(初阶)第一节:数据结构概论-CSDN博客 从本文正式进入对数据结构的讲解,开始前友友们要有C语言的基础,熟练掌握动态内存管理、结构体、指针等章节,方便后续的学习。 目录 顺序表(Sequen…...
鸿蒙OS元服务开发:【(Stage模型)设置应用主窗口】
一、设置应用主窗口说明 在Stage模型下,应用主窗口由UIAbility创建并维护生命周期。在UIAbility的onWindowStageCreate回调中,通过WindowStage获取应用主窗口,即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性&…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
