【设计模式】之责任链模式

news/2024/5/17 12:51:10

系列文章目录

  • 【设计模式】之策略模式


文章目录

系列文章目录

前言

一、什么是责任链模式

二、有什么使用场景呢

三、如何使用责任链模式

总结


前言

上次我们了解了设计模式中的策略模式,今天我们继续学习责任链模式。🌈


一、什么是责任链模式

为请求创建了一个接受者对象的链。为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。举个通俗易懂的例子,就是我们撸串的时候,我们一般都是从签的上方一个一个往下撸的,责任链模式就跟这个类似。

二、有什么使用场景呢

责任链模式因为可以灵活地配置处理者的顺序和数量,而不需要修改客户端代码。所以责任链模式在项目实战中用处广泛。

  • JDK中的异常处理机制就使用了责任链模式。当某个方法抛出异常时,首先会在方法内部寻找try-catch块来捕获异常,如果没有找到,就会将异常向上一层抛出,直至找到合适的catch块处理。
  • Spring框架中的拦截器链机制也使用了责任链模式。拦截器链是通过将各个拦截器按照一定的顺序连接起来形成一个链条,在请求处理过程中按顺序调用每个拦截器的相应方法来完成一系列操作。

责任链模式还可以用于处理日志记录、用户权限验证等场景。

三、如何使用责任链模式

我给大家举一个简单的例子,如:大学请假流程,我就以 院长-->导员-->任课老师这个流程来给大家解释。

首先,我们定义一个请假的接口,当然,用抽象类也阔以。

/**
* 说明: 请假接口
*/public interface TakeLeave {boolean doTakeLeave(User user);
}

然后呢,院长、导员、任课老师,分别去实现这个接口

/*院长*/
@Order(0)
@Component
public class deanHandler implements TakeLeave{@Overridepublic boolean doTakeLeave(User user) {if (user.getReason() == null || user.getReason().isEmpty()) {System.out.println("院长:没有请假理由,拒绝请假!");return false;}System.out.println("院长:已审核,提交给导员。");return true;}
}
/*导员*/
@Component
@Order(100)
public class GuideHandler implements TakeLeave{@Overridepublic boolean doTakeLeave(User user) {if (!user.getReason().contains("事") && !user.getReason().contains("病")) {System.out.println("导员:理由不充分,拒绝请假!");return false;}System.out.println("导员:已审核,提交给任课老师。");return true;}
}
/*任课老师*/
@Component
@Order(200)
public class LecturerHandler implements TakeLeave{@Overridepublic boolean doTakeLeave(User user) {System.out.println("任课老师:已同意学生请假。");return true;}
}

大家可以注意到,我Order里面优先级的数字设置的特别大,设置大一点可以方便后续我们可以继续扩展这个链,比如说:校验的时候,有用户名校验order(1)、手机校验order(2),后续扩展的时候,如过你想在添加一种校验规则,就只能在后面添加,如果有一些场景需要添加在两者中间,我们就需要重新修改order里面的数字。

设置责任链的协调者

@Component
public class LeaveHandlerChain {@Autowiredprivate List<TakeLeave> leaveHandlers;public boolean handleLeaveRequest(User user) {for (TakeLeave handler : leaveHandlers) {if (!handler.doTakeLeave(user)) {// 如果任何一个处理者返回false,则整个链结束return false;}}return true;}
}

进行测试

 @Autowiredprivate LeaveHandlerChain leaveHandlerChain;@Testvoid test1(){User user = new User();user.setName("小杰不秃头");user.setReason("家里有事,需要请假");//user.setReason("");boolean isApproved  = leaveHandlerChain.handleLeaveRequest(user);if (isApproved) {System.out.println("请假已批准!");} else {System.out.println("请假被拒绝!");}}/*
院长:已审核,提交给导员。
导员:已审核,提交给任课老师。
任课老师:已同意学生请假。
请假已批准!
*/
/*
院长:没有请假理由,拒绝请假!
请假被拒绝!
*/

总结

  • 优点:请求的发送者和接受者解耦;可以控制执行顺序;符合开闭原则单一职责原则
  • 缺点:对比较长的职责链,请求处理可能会涉及多个处理对象,性能会受到影响;增加了客户端的复杂性,可能会造成循环调用。

大家不可盲目为了使用设计模式而去使用设计模式,一定要结合具体的业务场景,选择最优的解决方法。

今天的分享就到这里,我们下个设计模式见🥳


http://www.mrgr.cn/p/05224324

相关文章

【项目构建】04:动态库与静态库制作

OVERVIEW 1.编译动态链接库&#xff08;1&#xff09;编译动态库&#xff08;2&#xff09;链接动态库&#xff08;3&#xff09;运行时使用动态库 2.编译静态链接库&#xff08;1&#xff09;编译静态库&#xff08;2&#xff09;链接静态库&#xff08;3&#xff09;运行时使…

C#反射应用

1.根据类名名称生成类实例 CreateInstance后面的参数部分一定要和所构造的类参数数量对应&#xff0c;即使设置参数默认值&#xff0c;也不可省略。 2.只知道类名&#xff0c;需要将该类作为参数调用泛型接口。 3.只知道类名&#xff0c;需要将该类的数组作为参数调用泛型接口…

php合并时间区间

需要写一段合并时间区间的代码,写个demo记录下 <?php $arr = [["2024-04-16 11:25:46", "2024-04-16 12:19:21"],["2024-04-16 03:14:06", "2024-04-16 10:13:21"],["2024-04-16 13:14:59", "2024-04-16 15:44:46…

罗宾斯《管理学》第15版笔记/课后习题/考研真题答案

第Ⅰ篇 管理导论 第1章 工作场所中的管理者和你 1.1 知识结构导图 1.2 考点难点归纳 1.3 课后习题详解 1.4 考研真题详解 附加模块一 管理史 知识结构导图 考点难点归纳 课后习题详解 考研真题详解 第2章 决 策 2.1 知识结构导图 2.2 考点难点归纳 2.3 课后习题详解…

王道数据结构个人向笔记-第二章(线性表)

目录2.1 线性表的定义和基本操作2.2 顺序表2.2.1 顺序表的定义2.2.2 顺序表的插入、删除(实现是基于静态分配)2.2.3 顺序表的查找2.3 链表2.3.1 单链表的定义2.3.2 单链表的插入删除2.3.3 单链表的查找2.3.4 单链表的建立2.3.4 双链表2.3.5 循环链表2.1 线性表的定义和基本操…

配置 Trunk,实现相同VLAN的跨交换机通信

1.实验环境 公司的员工人数已达到 100 人&#xff0c;其网络设备如图所示。现在的网络环境导致广播较多网速慢&#xff0c;并且也不安全。公司希望按照部门划分网络&#xff0c;并且能够保证一定的网络安全性。 其网络规划如下。 PC1和 PC3为财务部&#xff0c;属于VLAN 2&…

centos7 openresty lua 自适应webp和缩放图片

目录 背景效果图准备安装cwebp等命令&#xff0c;转换文件格式安装ImageMagick&#xff0c;压缩文件下载Lua API 操控ImageMagick的依赖包 代码参考 背景 缩小图片体积&#xff0c;提升加载速度&#xff0c;节省流量。 效果图 参数格式 &#xff1a; ?image_processformat,…

短视频素材哪个App最好?短视频素材哪里有免费的?

在数字媒体的黄金时代&#xff0c;富有创意的视频内容已成为吸引观众的关键。高质量的视频素材不仅能增强视觉效果&#xff0c;还能提升整体叙述的力度。以下列出了一系列全球顶尖的视频素材提供网站&#xff0c;它们将为你的广告制作、社交媒体或任何视频项目提供极具影响力的…

Java安全基础之Java反射机制和ClassLoader类加载机制

反射机制允许程序在运行时检查和操作类、对象、方法以及属性的信息。类加载机制负责将类的字节码加载到内存中,并且在运行时动态地链接和初始化类。目录Java 反射机制反射 java.lang.RuntimeClassLoader 类加载机制URLClassLoaderloadClass() 与 Class.forName() 的区别? Jav…

高中生一定就会了么???(i)

\(题源:2023星光杯数学思维能力测评(小学组)第一试\)\(表示离谱\)

打破失联困境:门店如何利用AI智能名片B2B2C商城小程序重构与消费者的紧密连接?

在如今这个消费者行为日益碎片化的时代&#xff0c;门店经营者们时常感叹&#xff1a;消费者进店如同一场不期而遇的缘分&#xff0c;然而一旦离开门店&#xff0c;就仿佛消失在茫茫人海中&#xff0c;难以再觅其踪迹。这种“进店靠缘分&#xff0c;离店就失联”的困境&#xf…

鸿蒙安装apk软件失败(不支持该设备)

1.关闭纯净模式增强模块 2.给文件管理器一个权限,一个安装外部来源应用的权限魔芋爽要犯了.jpg1.关闭纯净血压增高模块 2.安装外部来源(默认文件管理器是没有权限的) 3.没登华为账号,等七天过了再来试试后续(matepad11.5就是垃圾,快退!.jpg)

Outlook大附件插件 有效解决附件大小限制问题

很多企业都是使用Outlook来进行邮件的收发&#xff0c;可是由于附件大小有限&#xff0c;导致很多大文件发不出去&#xff0c;就会产生Outlook大附件插件这种业务需求。 邮件系统在发送大文件时面临的限制问题主要如下&#xff1a; 1、附件大小限制&#xff1a;大多数邮件服务…

1. SpringBoot 入门

1. SpringBoot 简介 SpringBoot是由Pivotal团队提供的全新框架,可以帮助我们开发基于Spring的、独立的、生产级的应用程序。​ 其中SpringBoot的官网是:Spring Boot Reference DocumentationSpringBoot的主要目标是:为所有Spring开发提供更快的入门体验开箱即用,提供了自动…

uniapp视频播放器(h5+app)

关于uniapp视频播放器遇到的一些问题&#xff0c;mark下。 中途遇到了很多问题&#xff0c;如果有相同的伙伴遇到了类似的&#xff0c;欢迎交流 官方的video播放器在app上不友好&#xff0c;有以下功能不支持。 loadedmetadata、controlstoggle不支持导致只能手写控制层。 不…

mysql连接不上,服务中找不到mysql

分析 因为太久没使用mysql,服务自动删除了解决 注册/安装服务 win+x,a,以管理员打开powershell(或者使用cmd,随你) # 注意此处需要引号,因为有空格 # 1. cd到mysql的可执行文件,如果记不得或者像我一样懒,直接everything搜索mysqld.exe即可 cd C:\Program Files\MySQL\My…

星趴解包教程

目录#1 提取资源文件#2 解密#3 读取资源#4 导出资源#4.1 导出单个 / 少量资源#4.2 按种类导出资源#5 资源去重(可选) 本篇文章偏小白向,有一定基础的可以选择性阅读 本文仅供学习交流使用,请勿用于商业用途。更新至 2024.5.2, 星趴版本号 v1.2.3_20240430_123a#1 提取资源文…

快速了解Django:核心概念解析与实践指南

title: 快速了解Django&#xff1a;核心概念解析与实践指南 date: 2024/5/1 20:31:41 updated: 2024/5/1 20:31:41 categories: 后端开发 tags: Django核心路由系统视图系统ORM管理中间件Web框架登录装饰器 第一章&#xff1a;Django简介 背景和发展历程&#xff1a; Djan…

站立会议和燃尽图10

站立会议和燃尽图10 一、小组情况 组长:李宏威 组员:董泽豪 队名:隐约雷名 二、Scrum例会 时间:2024年4月29日 出席人员:李宏威,董泽豪 要求1 工作照片要求2 时间跨度 2024年4月29日 7:00 至 2024年4月29日 7:20 共计 20 分钟 要求3 地点 石家庄铁道大学 要求4 立会内容包…