一个个顺序挨着来 - 责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)

  • 责任链模式(Chain of Responsibility Pattern)
    • 责任链模式(Chain of Responsibility Pattern)概述
      • 责任链结构图
      • 责任链模式概述
      • 责任链模式涉及的角色
    • talk is cheap, show you my code
    • 总结

责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链条传递,直到有一个处理者能够处理它为止。这种模式避免了请求发送者和接收者之间的耦合,并且可以动态地指定一组处理者来处理请求。每个处理者都包含对下一个处理者的引用,如果当前处理者不能处理请求,它会将请求转发给下一个处理者。

太抽象了,举个现实生活中的例子
生活中,我们可能会遇到需要报销的生活场景。但是报销的时候,每个人的报销权限不一样。比如金额比较小的时候,你的领导就可以帮你审批;但是如果金额超过了你领导的审核范围,你的领导可能就把报销的交给他的上一层领导处理;他的上一层领导如果能处理就处理,处理不了,就沿着审批链条再往上进行审批。

责任链模式(Chain of Responsibility Pattern)概述

责任链结构图

在这里插入图片描述

责任链模式概述

  • 定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
  • 目的:解耦请求的发送者与接收者,提供一个灵活的方式来处理请求,支持动态添加或移除处理逻辑。

责任链模式涉及的角色

  1. 抽象处理者(Handler):声明了所有具体处理者必须实现的方法,通常是handle()方法。此外,它还可能包含一个指向下一个处理者的引用。
public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(String request);
}
  1. 具体处理者(ConcreteHandler):实现了Handler接口的具体类。
public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("Handled by ConcreteHandlerA");} else {if (successor != null) {successor.handleRequest(request);}}}
}public class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("Handled by ConcreteHandlerB");} else {if (successor != null) {successor.handleRequest(request);}}}
}
  1. 客户端(Client):客户端创建具体的处理者对象,并根据需要将它们链接起来形成一条责任链。然后,客户端将请求传递给链中的第一个处理者。
public class Client {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();// 构建责任链handlerA.setSuccessor(handlerB);// 发送请求handlerA.handleRequest("A"); // Handled by ConcreteHandlerAhandlerA.handleRequest("B"); // Handled by ConcreteHandlerBhandlerA.handleRequest("C"); // Not handled, no output or error}
}

talk is cheap, show you my code

我们还是利用本次要介绍的设计模式来实现我们给出的例子。

  1. 首先,我们定义一个ApprovalRequest类来表示审批请求:
public class ApprovalRequest {private double amount;private String description;private boolean isApproved = false;public ApprovalRequest(double amount, String description) {this.amount = amount;this.description = description;}public double getAmount() {return amount;}public String getDescription() {return description;}public boolean isApproved() {return isApproved;}public void setApproved(boolean approved) {isApproved = approved;}
}
  1. 接下来,我们定义一个Approver接口,所有审批者都将实现这个接口:
public interface Approver {void processRequest(ApprovalRequest request);Approver getNextApprover();void setNextApprover(Approver nextApprover);
}
  1. 我们为不同的审批级别创建具体的审批者类。例如,部门经理(DepartmentManager)、总监(Director)和CEO(ChiefExecutiveOfficer)
public class DepartmentManager implements Approver {private Approver nextApprover;private static final double LIMIT = 5000.0;public DepartmentManager() {}@Overridepublic void processRequest(ApprovalRequest request) {if (request.getAmount() <= LIMIT) {System.out.println(request.getDescription() + " is approved by Department Manager.");request.setApproved(true);} else {if (nextApprover != null) {nextApprover.processRequest(request);} else {System.out.println(request.getDescription() + " was rejected.");request.setApproved(false);}}}@Overridepublic Approver getNextApprover() {return nextApprover;}@Overridepublic void setNextApprover(Approver nextApprover) {this.nextApprover = nextApprover;}
}public class Director implements Approver {private Approver nextApprover;private static final double LIMIT = 20000.0;// Similar methods as in DepartmentManager// ...
}public class ChiefExecutiveOfficer implements Approver {private Approver nextApprover;// No limit for CEO, all requests will be approved or rejected here// Similar methods as in DepartmentManager and Director// ...
}
  1. 最后,我们可以编写一个客户端类来测试这个责任链:
public class Client {public static void main(String[] args) {ApprovalRequest request1 = new ApprovalRequest(4500, "Office supplies");ApprovalRequest request2 = new ApprovalRequest(12000, "New computer");ApprovalRequest request3 = new ApprovalRequest(25000, "Conference room renovation");Approver departmentManager = new DepartmentManager();Approver director = new Director();Approver ceo = new ChiefExecutiveOfficer();departmentManager.setNextApprover(director);director.setNextApprover(ceo);departmentManager.processRequest(request1);System.out.println("Request1 approved? " + request1.isApproved());departmentManager.processRequest(request2);System.out.println("Request2 approved? " + request2.isApproved());departmentManager.processRequest(request3);System.out.println("Request3 approved? " + request3.isApproved());}
}

在这个客户端类中,我们创建了三个审批请求,并设置了审批链。然后,我们依次处理这些请求,并打印出它们是否被批准。

总结

责任链可以帮助我们降低耦合度;增加灵活性;可以帮助我们更好地组织代码。我们上面实现地责任链模式是类似与拦截器的那种方式。责任链还可以设计为一些别的方式。责任链模式一般适用于日志记录;审批流程等等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66539.shtml

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

相关文章

Laravel 新 WebSocket 服务 Reverb 使用指南

旧篇 > Laravel/Lumen 中使用 Echo Socket.IO-Client 实现网页即时通讯广播 https://blog.csdn.net/maxsky/article/details/130394420 已过时 与时俱进&#xff0c;Laravel 官方在 2024 年 7 月发布了 laravel/reverb 包的正式版&#xff0c;因为之前使用的 laravel-echo-…

网工考试下午题目笔记

1、在防火墙设备中&#xff0c;配置双出口链路有提高总带宽、链路负载均衡、提高可靠性的作用&#xff0c;通过配置链路聚合提高总带宽&#xff0c;通过配置策略路由提高链路负载均衡 防火墙工作模式有路由模式(防火墙接口配有IP地址)、透明模式(防火墙相当于不存在)、混合模式…

WEB攻防-通用漏洞_文件上传_黑白盒审计流程

目录 前置知识点 Finecms-CMS文件上传 ​编辑 Cuppa-Cms文件上传 Metinfo-CMS 文件上传 前置知识点 思路&#xff1a; 黑盒就是寻找一切存在文件上传的功能应用 1 、个人用户中心是否存在文件上传功能 2 、后台管理系统是否存在文件上传功能 3 、字典目录扫描探针文件上传构…

Agentic RAG 解释

RAG&#xff08;检索增强生成&#xff09;通过提供来自外部知识源的相关背景来帮助提高 LLM 答案的准确性和可靠性。 Agentic RAG 是高级 RAG 版本&#xff0c;它使用 AI 代理来更加自主地行动。 Agentic RAG 执行以下操作 查询理解、分解和重写检索策略选择知识库管理结果综…

apex安装

安装过程复杂曲折&#xff0c;网上说的很多办法&#xff0c;貌似成功了&#xff0c;实际还是没起作用。 先说成功过程&#xff0c;执行下面命令&#xff0c;安装成功&#xff08;当然&#xff0c;前提是你要先配置好编译环境&#xff09;&#xff1a; &#xff08;我的环境&a…

shell-条件判断

目录 一、条件判断 1.按照文件类型进行判断 2.按照文件权限进行判断 3.两个文件之间进行比较 4.两个整数之间进行比较 5.字符串的判断 6.多重条件判断 二、if条件判断 1.单分支if条件语句 2.双分支if条件语句 &#xff08;1&#xff09;判断某文件是否存在 &#x…

基于FPGA的出租车里程时间计费器

基于FPGA的出租车里程时间计费器 功能描述一、系统框图二、verilog代码里程增加模块时间增加模块计算价格模块上板视频演示 总结 功能描述 &#xff08;1&#xff09;&#xff1b;里程计费功能&#xff1a;3公里以内起步价8元&#xff0c;超过3公里后每公里2元&#xff0c;其中…

将数组转换为laravel中的对象

将数组转换为laravel中的对象 在Laravel中&#xff0c;可以通过使用集合&#xff08;Collection&#xff09;来将数组转换为对象。集合是Laravel提供的一个强大的工具&#xff0c;用于处理数组数据。 将数组转换为Laravel中的对象的步骤如下&#xff1a; 首先&#xff0c;确…

jdk8升级JDK21(Springboot2.7.18升级Springboot3.4.0)

目录 背景&#xff1a; 一、maven升级 二、代码改造 2.1 javax替换为jakarta 2.2 swagger2升级swagger3相关更新 2.2.1 新增SpringDocConfig配置类 2.2.2 全局代码更新 2.2.3 全局代码替换&#xff08;普通正则替换&#xff09; 2.3 Mybatis Plus升级 2.4 logback.xm…

AI赋能跨境电商:魔珐科技3D数字人破解出海痛点

跨境出海进入狂飙时代&#xff0c;AI应用正在深度渗透并重塑着跨境电商产业链的每一个环节&#xff0c;迎来了发展的高光时刻。生成式AI时代的大幕拉开&#xff0c;AI工具快速迭代&#xff0c;为跨境电商行业的突破与飞跃带来了无限可能性。 由于跨境电商业务自身特性鲜明&…

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS NEXT】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二…

Ubuntu挂载云盘操作步骤

1. 查看磁盘分区情况 使用 fdisk -l 命令查看当前系统中所有磁盘的分区情况&#xff0c;找到需要挂载的云盘设备&#xff0c;例如/dev/vdc。 2. 创建新分区 使用 fdisk /dev/vdc 命令对云盘进行分区操作&#xff1a; 输入n创建新分区。 输入p选择创建主分区。 输入1指定分区…

stm32u5串口点灯

通过对单个字符输入的拼接暂存&#xff0c;实现对字符串的比较控制灯的亮灭 char buf[32];char temp[32];while (1){printf("start\n\r");memset(temp,0, sizeof(temp));memset(buf,0, sizeof(buf));while(temp[0] !\r){memset(temp,0, sizeof(temp));HAL_UART_Rece…

PHP 5 6 7 8 9 各重要版本开发特性和选择简要说明

PHP开发&#xff0c;所用版本的选型 PHP5.4是最后一个支持纯正32位操作系统的版本&#xff0c;在Winxp下仍可使用。 PHP5.6是php5.x的最后一个稳定版本&#xff0c;时至今天&#xff0c;仍有很多用户网站系统在使用&#xff0c;网上仍有很多学习资料是基于这个版本&#xff0c;…

Xen 虚拟化技术在云计算平台中的应用详解

Xen 虚拟化技术在云计算平台中的应用详解 随着云计算的飞速发展&#xff0c;虚拟化技术成为构建云平台的核心支柱&#xff0c;而 Xen 作为一种高性能、开源的虚拟化技术&#xff0c;被广泛应用于云计算平台中。Xen 凭借其灵活的架构和出色的性能&#xff0c;为众多云服务商提供…

Elixir语言的正则表达式

Elixir语言中的正则表达式 引言 正则表达式是用于匹配文本模式的一种强大工具。在很多编程语言中&#xff0c;正则表达式被广泛应用于字符串的查找、替换和验证。Elixir作为一门现代化的函数式编程语言&#xff0c;也提供了对正则表达式的支持&#xff0c;方便开发者进行复杂…

MATLAB语言的正则表达式

MATLAB 中的正则表达式使用指南 引言 在数据处理和文本分析中&#xff0c;正则表达式是一种强大而灵活的工具。MATLAB 作为一种广泛应用于科学计算和数据分析的编程语言&#xff0c;提供了对正则表达式的支持&#xff0c;使得用户可以方便地进行字符串匹配与处理。本文将深入…

《Java 中 Thread 类的基本用法总结》

在 Java 编程中&#xff0c;Thread类是实现多线程的核心类之一。下面将对Thread类在创建线程、线程中断、线程等待、线程休眠和获取线程实例等方面的基本用法进行总结。 一、线程创建 继承 Thread 类 定义一个类继承自Thread类。重写run方法&#xff0c;run方法中包含了该线程…

Flannel:Kubernetes 网络方案的“轻骑兵”

Flannel&#xff1a;Kubernetes 网络方案的“轻骑兵” 在 Kubernetes 中&#xff0c;网络是连接所有组件的核心。每个 Pod 都需要一个独立的 IP&#xff0c;方便 Pod 间的通信&#xff0c;而 Flannel 正是解决这个问题的经典容器网络插件&#xff08;CNI&#xff09;。它简单、…

Android - NDK:编译可执行程序在android设备上运行

在android开发中&#xff0c;调试时会把C代码直接编译成可执行程序&#xff0c;运行在android设备上以确认其功能是否正常。 1、基于NDK编译可执行文件 2、push到 /data/local/tmp目录下 3、设置权限&#xff0c;执行。 ndk工程中build.gradle设置 groovy plugins {id com.a…