设计模式|责任链模式(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获取应用主窗口,即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
