设计模式|责任链模式(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获取应用主窗口,即可对其进行属性设置等操作。还可以在应用配置文件中设置应用主窗口的属性&…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
