当前位置: 首页 > news >正文

设计模式之职责链模式

什么是职责链模式

    职责链模式是避免请求发送者与接受者耦合在一起,让多个对象都可以接受到请求,从而将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。
    职责链模式包含以下几个角色:
        Handler(抽象处理者):定义处理请求的接口,一般是抽象类。由于不同的具体处理类处理请求的方式不同,因此在其中定义抽象处理请求的方法。因为每一个处理这的下家还是处理者,因此在抽象处理者中定义一个抽象处理者类型的对象作为下家的引用。
        ConcreteHandler(具体处理者):是抽象处理者的子类,实现了抽象处理者中定义的抽象方法用于处理用户请求。具体处理者有两大作用:一是处理请求,不同的具体处理者以不同的形式实现抽象处理者的方法。二是转发请求,当前处理类可将请求转发给下家。
    职责链模式可以分为纯的职责链模式和不纯的职责链模式:
        纯的职责链模式:要求具体处理者只能在两个行为中选择一个,要么承担全部责任,要么将责任转发给下家,不允许出现一个具体处理者承担了一部分或全部责任还要将责任转发给下家。
        不纯的职责链模式:允许请求被一个具体处理者处理部分或全部后在转发给下家,也可以不被任何处理者所处理。

职责链模式的优缺点

优点

  1. 一个对象无需知道是其他哪个对象处理请求,降低了系统耦合。
  2. 请求处理对象只需维护一个指向下家的的引用,简化对象的相互连接。
  3. 给对象分派职责时更加灵活,可以通过在运行时对该链进行动态增加或修改改变处理请求的职责。
  4. 增加新的处理请求时无需修改代码,符合开闭原则。

缺点

  1. 不保证每个请求都会被处理。
  2. 太长的职责链涉及更多的处理对象,会降低系统性能。
  3. 可能会造成循环调用陷入死循环。

职责链模式的应用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理在运行时决定。
  2. 不明确接受者的情况下,向多个对象中的一个提交请求。
  3. 可动态指定一组对象处理请求,客户端可以动态创建职责链处理请求,还可以改变处理请求的顺序。

职责链模式的案例

// 请求对象
public class PurchaseRequest implements Serializable {private int type = 0;private float price = 0.0f;private int id = 0;}// 抽象处理者
public abstract class Approver {Approver approver;String name;public Approver(String name) {this.name = name;}public void setApprover(Approver approver) {this.approver = approver;}public abstract void processRequest(PurchaseRequest purchaseRequest);}// 具体处理者
public class CollegeApprover extends Approver {public CollegeApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}public class DepartmentApprover extends Approver {public DepartmentApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() <= 5000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}}public class SchoolMasterApprover extends Approver {public SchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() > 30000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}public class ViceSchoolMasterApprover extends Approver {public ViceSchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");} else {approver.processRequest(purchaseRequest);}}
}

在这里插入图片描述

职责链模式在源码中的应用

org.apache.ibatis.plugin.InterceptorChain

// 在mybatis源码中,添加拦截器就是使用责任链模式
// pluginAll 通过这个方法可以添加定义好的拦截器实现
// 通过遍历 getInterceptors 就可以去请求每一个定义好的拦截器类
public class InterceptorChain {private final List<Interceptor> interceptors = new ArrayList<>();public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}public void addInterceptor(Interceptor interceptor) {interceptors.add(interceptor);}public List<Interceptor> getInterceptors() {return Collections.unmodifiableList(interceptors);}}

相关文章:

设计模式之职责链模式

什么是职责链模式 职责链模式是避免请求发送者与接受者耦合在一起&#xff0c;让多个对象都可以接受到请求&#xff0c;从而将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理为止。     职责链模式包含以下几个角色&#xff1a;    …...

MySQL入门篇-MySQL 8.0 延迟复制

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL 延迟复制 概述 MySQL的复制一般都很快&#xff0c;虽然有时候因为 网络原因、大事务等原因造成延迟&#xff0c;但是这个无法人为控制。 生产中可能会存在主库误操作&#xff0c;导致数据被删除了&#xff0c;Oracl…...

FPGA时序约束与分析 --- 实例教程(1)

注意&#xff1a; 时序约束辅助工具或者相关的TCL命令&#xff0c;都必须在 open synthesis design / open implemention design 后才能有效运行。 1、时序约束辅助工具 2、查看相关时序信息 3、一般的时序约束顺序 1、 时序约束辅助工具&#xff08;1&#xff09;时序约束编辑…...

go深拷贝和浅拷贝

1、深拷贝&#xff08;Deep Copy&#xff09;拷贝的是数据本身&#xff0c;创造一个样的新对象&#xff0c;新创建的对象与原对象不共享内存&#xff0c;新创建的对象在内存中开辟一个新的内存地址&#xff0c;新对象值修改时不会影响原对象值。既然内存地址不同&#xff0c;释…...

linux网络系统层面的配置、管理及操作命令汇总

前几篇文章一一介绍了LINUX进程管理控制命令&#xff0c;关于linux系统中的软件包管理内容等&#xff0c;作为一名运维工程师&#xff0c;前两天刚处理了一起linux网络层面的情况&#xff0c;那么今天这篇文章就以linux网络层面为主题吧。当说到linux网络系统层面&#xff0c;e…...

R数据分析:孟德尔随机化中介的原理和实操

中介本身就是回归&#xff0c;基本上我看到的很多的调查性研究中在中介分析的方法部分都不会去提混杂&#xff0c;都是默认一个三角形画好&#xff0c;中介关系就算过去了&#xff0c;这里面默认的逻辑就是前两步回归中的混杂是一样的&#xff0c;计算中介效应的时候就自动消掉…...

【C++】 类和对象 (下)

文章目录&#x1f4d5;再谈构造函数1. 构造函数体赋值2. 初始化列表3. explicit 关键字&#x1f4d5;static 成员1. 概念2. static 成员变量3. static 成员函数&#x1f4d5; 友元1. 友元函数2. 友元类&#x1f4d5;内部类&#x1f4d5;编译器优化&#x1f4d5;再谈构造函数 1…...

asp获取毫秒时间戳的方法 asp获取13位时间戳的方案

一、背景。时间戳就是计算当前与"1970-01-01 08:00:00"的时间差&#xff0c;在asp中通常是使用Datediff函数来计算两个日期差&#xff0c;代码&#xff1a;timestamp Datediff("s", "1970-01-01 08:00:00",now)返回结果&#xff1a;1675951060可…...

Python基础篇(十五)-- Python程序接入MySQL数据库

程序运行时&#xff0c;数据都在内存中&#xff0c;程序终止时&#xff0c;需要将数据保存到磁盘上。为了便于程序保存和读取&#xff0c;并能直接通过条件快速查询到指定数据&#xff0c;数据库(Database)应运而生&#xff0c;本篇主要学习使用Python操作数据库&#xff0c;在…...

程序员不得不知道的 API 接口常识

说实话&#xff0c;我非常希望自己能早点看到本篇文章&#xff0c;大学那个时候懵懵懂懂&#xff0c;跟着网上的免费教程做了一个购物商城就屁颠屁颠往简历上写。 至今我仍清晰地记得&#xff0c;那个电商教程是怎么定义接口的&#xff1a; 管它是增加、修改、删除、带参查询…...

【项目精选】基于Java的银行排号系统的设计与实现

银行排号系统是为解决一些服务业营业大厅排队问题而设计的&#xff0c;它能够有效地提高工作人员的工作效率&#xff0c;也能够使顾客合理的安排等待时间&#xff0c;让顾客感到服务的公平公正。论文首先讨论了排号系统的背景、意义、应用现状以及研究与开发现状。本文在对C/S架…...

前端 基于 vue-simple-uploader 实现大文件断点续传和分片上传

文章目录一、前言二、后端部分新建Maven 项目后端pom.xml配置文件 application.ymlHttpStatus.javaAjaxResult.javaCommonConstant.javaWebConfig.javaCheckChunkVO.javaBackChunk.javaBackFileList.javaBackChunkMapper.javaBackFileListMapper.javaBackFileListMapper.xmlBac…...

解决报错: ERR! code 128npm ERR! An unknown git error occurred

在github下载的项目运行时&#xff0c;进行npm install安装依赖时&#xff0c;出现如下错误&#xff1a;npm ERR! code 128npm ERR! An unknown git error occurrednpm ERR! command git --no-replace-objects ls-remote ssh://gitgithub.com/nhn/raphael.gitnpm ERR! gitgithu…...

聊城高新技术企业认定7项需要注意的问题 山东同邦科技分享

聊城高新技术企业认定7项需要注意的问题 山东同邦科技分享 山东省高新技术企业认定办公室发布《关于开展2021年度本市高新技术企业认定管理工作的通知》&#xff0c;高企认定中有哪些问题需要注意呢&#xff1f;下面我们一起来看一下。 一、知识产权 知识产权数量和质量双达…...

菊乐食品更新IPO招股书:收入依赖单一地区,规模不及认养一头牛

近日&#xff0c;四川菊乐食品股份有限公司&#xff08;下称“菊乐食品”&#xff09;预披露更新招股书&#xff0c;准备在深圳证券交易所主板上市&#xff0c;保荐机构为中信建投证券。据贝多财经了解&#xff0c;这已经是菊乐食品第四次冲刺A股上市&#xff0c;此前三次均未能…...

Elasticsearch安装IK分词器、配置自定义分词词库

一、分词简介 在Elasticsearch中&#xff0c;假设搜索条件是“华为手机平板电脑”&#xff0c;要求是只要满足了其中任意一个词语组合的数据都要查询出来。借助 Elasticseach 的文本分析功能可以轻松将搜索条件进行分词处理&#xff0c;再结合倒排索引实现快速检索。Elasticse…...

Linux嵌入式开发——shell脚本

文章目录Linux嵌入式开发——shell脚本一、shell脚本基本原则二、shell脚本语法2.1、编写shell脚本2.2、交互式shell脚本2.3、shell脚本的数值计算2.4、test命令&&运算符||运算符2.5、中括号[]判断符2.6、默认变量三、shell脚本条件判断if thenif then elsecase四、she…...

CV【5】:Layer normalization

系列文章目录 Normalization 系列方法&#xff08;一&#xff09;&#xff1a;CV【4】&#xff1a;Batch normalization Normalization 系列方法&#xff08;二&#xff09;&#xff1a;CV【5】&#xff1a;Layer normalization 文章目录系列文章目录前言2. Layer normalizati…...

跳跃游戏 II 解析

题目描述给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处:0 < j < nums[i] i j < n返回到达 nums[n - 1] 的…...

易基因|猪肠道组织的表观基因组功能注释增强对复杂性状和人类疾病的生物学解释:Nature子刊

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。2021年10月6日&#xff0c;《Nat Commun》杂志发表了题为“Pig genome functional annotation enhances the biological interpretation of complex traits and human disease”的研究论文…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

简单聊下阿里云DNS劫持事件

阿里云域名被DNS劫持事件 事件总结 根据ICANN规则&#xff0c;域名注册商&#xff08;Verisign&#xff09;认定aliyuncs.com域名下的部分网站被用于非法活动&#xff08;如传播恶意软件&#xff09;&#xff1b;顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…...

汇编语言学习(三)——DoxBox中debug的使用

目录 一、安装DoxBox&#xff0c;并下载汇编工具&#xff08;MASM文件&#xff09; 二、debug是什么 三、debug中的命令 一、安装DoxBox&#xff0c;并下载汇编工具&#xff08;MASM文件&#xff09; 链接&#xff1a; https://pan.baidu.com/s/1IbyJj-JIkl_oMOJmkKiaGQ?pw…...

2025-06-01-Hive 技术及应用介绍

Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具&#xff0c;它为海量结构化数据提供类 SQL 的查询能力&#xf…...

如何在Spring Boot中使用注解动态切换实现

还在用冗长的if-else或switch语句管理多个服务实现? 相信不少Spring Boot开发者都遇到过这样的场景:需要根据不同条件动态选择不同的服务实现。 如果告诉你可以完全摆脱条件判断,让Spring自动选择合适的实现——只需要一个注解,你是否感兴趣? 本文将详细介绍这种优雅的…...

CSP信奥赛C++常用系统函数汇总

# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout&#xff08;<iostream>&#xff09; cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化&#xff1a;ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...

【汇编逆向系列】四、函数调用包含单个参数之Double类型-mmword,movsd,mulsd,addsd指令,总结汇编的数据类型

一、汇编代码 上一节开始&#xff0c;讲到了很多debug编译独有的汇编方式&#xff0c;为了更好的区分release的编译器优化和debug的区别&#xff0c;从本章节开始将会提供debug和release的汇编用作对比 Debugb编译 single_double_param:00000000000000A0: F2 0F 11 44 24 08…...