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

系列文章目录

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


文章目录

系列文章目录

前言

一、什么是责任链模式

二、有什么使用场景呢

三、如何使用责任链模式

总结


前言

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


一、什么是责任链模式

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

二、有什么使用场景呢

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

  • 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.mzph.cn/web/5900.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GZIP文件格式解析和Inflate静态Huffman解压缩

GZIP是封装了Deflate压缩的格式文件&#xff1b;Deflate使用了无压缩、HuffmanLZ77进行压缩&#xff1b;解压是Inflate&#xff0c;Huffman包括静态Huffman压缩和动态Huffman压缩两种模式。 Java语言实现了GZIP格式解析、Inflate的静态Huffman解压缩、CRC32校验 算法。 gzip文…

精准测试-Vue前端调用链影响变更分析之一

Vue前端调用链影响变更分析之一 一、背景二、工具调研1、 工具介绍&#xff1a;2、工具使用 三、工具落地集成方案&#xff08;待后续补充&#xff09;变更影响较为简单的实现变更影响较为复杂的实现1、全局关系数据库的构建2、变更影响的简单实现3、变更影响的复杂实现 一、背…

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

ElasticSearch教程入门到精通——第一部分&#xff08;基于ELK技术栈elasticsearch 8.x新特性&#xff09; 1. ElasticSearch安装&#xff08;略&#xff09;2. ElasticSearch基础功能2.1 索引操作2.1.1 创建索引2.1.2 Head 索引2.1.3 查询索引2.1.3.1 查询单独索引2.1.3.2 查询…

Instal IIS on Windows Server 2022 Datacenter

和以往版本一样&#xff0c;没有什么不同&#xff0c;So easy&#xff01; WinR - ServerManager.exe 打开服务器管理器&#xff0c;点击【添加角色和功能】&#xff0c;选择自己想要的角色和功能。 一、开始之前&#xff1a;帮助说明&#xff0c;点击【下一步】&#xff1b;…

双塔模型模型结构、样本选择、训练方式、线上服务、模型更新

召回模型目的是快速选取用户可能感兴趣的物品&#xff0c;凡事用户可能感兴趣的都取回来 然后交给后续排序模型逐一甄别。 双塔模型结构 不止能使用id特征&#xff08;能使用id之外的其他特征&#xff09;&#xff0c;用户侧能用画像等其他特征&#xff0c;包括离散特征和连续…

vue3 element-plus 让el-container占满屏幕

在刚开始用element-plus的布局时&#xff0c;发现无法占满屏幕&#xff1a; 在App.vue中添加如下css代码&#xff1a; <style>html, body, #app {margin: 0;padding: 0;height: 100%;} </style>同时布局代码所在的component如下所示&#xff1a; <template&g…

C++ | Leetcode C++题解之第64题最小路径和

题目&#xff1a; 题解&#xff1a; class Solution { public:int minPathSum(vector<vector<int>>& grid) {if (grid.size() 0 || grid[0].size() 0) {return 0;}int rows grid.size(), columns grid[0].size();auto dp vector < vector <int>…

SSL通信、证书认证原理和失败原因

目录 SSL通信SSL认证原理SSL证书认证失败的原因分析 SSL通信 SSL通信指的是使用SSL&#xff08;Secure Sockets Layer&#xff09;协议进行的加密通讯。SSL是一种标准的安全技术&#xff0c;用于建立一个加密链接&#xff0c;确保从用户的浏览器到服务器之间的数据传输是私密和…

自定义 Dockerfile 构建 PostgreSQL 15 编译版 Docker 镜像

BG 前几日 Sean 老师发布了一篇文章 – PostgreSQL安装(一): 再简单点儿&#xff0c;用Docker?, 介绍如何快速安装启动 PostgreSQL 数据库。 本文再稍微延伸一点&#xff0c;介绍一下如何自定义 Dockerfile&#xff0c;加入自己想要预制的参数&#xff0c;构建一个自定义的 …

react核心知识

1. 对 React 的理解、特性 React 是靠数据驱动视图改变的一种框架&#xff0c;它的核心驱动方法就是用其提供的 setState 方法设置 state 中的数据从而驱动存放在内存中的虚拟 DOM 树的更新 更新方法就是通过 React 的 Diff 算法比较旧虚拟 DOM 树和新虚拟 DOM 树之间的 Chan…

web响应式页面是啥要注意啥

Web响应式页面是一种能够根据不同设备和屏幕尺寸自动调整布局、内容和功能的网页设计方式。这种设计方式的核心在于确保网页在各种平台上都能够正确显示和操作&#xff0c;为用户提供一致且良好的浏览体验。 在设计Web响应式页面时&#xff0c;有几个关键的注意事项&#xff1a…

JavaScript中的深拷贝与浅拷贝

目录 引言&#xff1a; 一、浅拷贝&#xff08;Shallow Copy&#xff09; 二、深拷贝&#xff08;Deep Copy&#xff09; 实现深拷贝的方法&#xff1a; 1.使用JSON.parse(JSON.stringify(obj)) 2.使用递归实现深拷贝 三、总结 引言&#xff1a; 在JavaScript中&#xff0…

安卓接入wwise

第一步&#xff1a; #include "com_hs_androidjnidemo_MainActivity.h" #include "jni.h" #include <stdio.h> #include <YLWwiseEngine.h> #include <AK/SoundEngine/Common/AkTypes.h>//全局变量 gaden JavaVM *g_vm;//0.JNI_OnLoad J…

暂时性解决JDK21 无法使用 TimeUnit的问题

我调用 java.util中的TimeUtil时。 JDK17及以下版本时这样正常可以使用的 但是在JDK21中却是个TimeUtil.class文件 我没法调用内部的属性 解决方式&#xff1a;是我卸载了21&#xff0c;使用的了JDK17. 使用场景&#xff1a;原本项目是基于JDK8 的&#xff0c;但是因为其他…

关于kline-chart图表程序的一些构想

之前在这儿&#xff1a;一个python实现的kline-chart图表程序&#xff08;二&#xff09;_klinechart教程-CSDN博客 实现了一个看起来不错的K线图表的功能&#xff0c;可以按要求生成对应的图形。不过还是有些问题。比如我想做一个缠论关于笔&#xff0c;线段&#xff0c;中枢等…

什么是限流?常见的限流算法

目录 1. 什么是限流 2. 常见限流算法 3. 固定窗口算法 4. 滑动窗口算法 5. 漏桶算法 6. 令牌桶算法 7. 限流算法选择 1. 什么是限流 限流&#xff08;Rate Limiting&#xff09;是一种应用程序或系统资源管理的策略&#xff0c;用于控制对某个服务、接口或功能的访问速…

Sortable 拖拽行实现el-table表格顺序号完整例子,vue 实现表格拖拽行顺序号完整例子

npm install sortable<template><vxe-modalref"modalRef"v-model"showModal"title"详情"width"70vw"height"60vh"class"his"transfer><el-table ref"tableRef" :data"tableData&q…

原生 php 实现redis缓存配置和使用方法

在 PHP 中实现 Redis 缓存的配置和方法&#xff0c;首先需要确保你的服务器上安装了 Redis&#xff0c;并且 PHP 安装了 Redis 扩展。以下是一个基本的步骤和示例&#xff1a; 1. 安装 Redis 和 PHP Redis 扩展 Redis 安装&#xff1a;根据你的服务器操作系统和配置&#xff…

机器学习-06-聚类算法总结

聚类总结 1.聚类 机器学习 任务 聚类 无label的 分类 label是离散的 回归 label是连续的 2.聚类算法-kmeans 划分聚类 思想&#xff1a; D中选取k个作为初始质心 repeat 计算所有点与质心的距离&#xff0c;分到近的质心簇 更新簇之间的质心 until 质心不改 不足&#xff…