【设计模式】【行为型模式(Behavioral Patterns)】之责任链模式(Chain of Responsibility Pattern)

1. 设计模式原理说明

责任链模式(Chain of Responsibility Pattern) 是一种行为设计模式,它允许你将请求沿着处理者链进行发送。每个处理者都可以处理请求,或者将其传递给链上的下一个处理者。这种模式使得多个对象都有机会处理请求,而无需提前指定具体的处理者。这样可以减少请求发送者和接收者之间的耦合。

主要角色
  1. Handler(抽象处理者):定义了一个处理请求的接口,通常包含一个后继连接,用于指向下一个处理者。
  2. ConcreteHandler(具体处理者):实现了处理请求的方法,判断是否处理该请求,如果不能处理则将请求转发给下一个处理者。
  3. Client(客户端):创建处理者对象并组织成一条链,向链中的第一个处理者提交请求。

2. UML 类图及解释

UML 类图
+-----------------+
|    Handler      |
|-----------------|
| - successor: Handler |
| - setSuccessor(successor: Handler) |
| - handleRequest(request: Request) |
+-----------------+^||v
+-----------------+
| ConcreteHandlerA|
|-----------------|
| - handleRequest(request: Request) |
+-----------------+^||v
+-----------------+
| ConcreteHandlerB|
|-----------------|
| - handleRequest(request: Request) |
+-----------------+
类图解释
  • Handler:定义了处理请求的接口,包含一个后继连接(successor),用于指向下一个处理者。
  • ConcreteHandlerA 和 ConcreteHandlerB:实现了处理请求的方法,判断是否处理该请求,如果不能处理则将请求转发给下一个处理者。
  • Client:创建处理者对象并组织成一条链,向链中的第一个处理者提交请求。

3. 代码案例及逻辑详解

Java 代码案例
// 抽象处理者
abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(int request);
}// 具体处理者 A
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(int request) {if (request >= 0 && request < 10) {System.out.println("ConcreteHandlerA handled request " + request);} else if (successor != null) {successor.handleRequest(request);}}
}// 具体处理者 B
class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(int request) {if (request >= 10 && request < 20) {System.out.println("ConcreteHandlerB handled request " + request);} else if (successor != null) {successor.handleRequest(request);}}
}// 客户端
public class Client {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();handlerA.setSuccessor(handlerB);handlerA.handleRequest(5);  // 应由 ConcreteHandlerA 处理handlerA.handleRequest(15); // 应由 ConcreteHandlerB 处理handlerA.handleRequest(25); // 没有处理者可以处理}
}
C++ 代码案例
#include <iostream>// 抽象处理者
class Handler {
protected:Handler* successor;
public:void setSuccessor(Handler* successor) {this->successor = successor;}virtual void handleRequest(int request) = 0;
};// 具体处理者 A
class ConcreteHandlerA : public Handler {
public:void handleRequest(int request) override {if (request >= 0 && request < 10) {std::cout << "ConcreteHandlerA handled request " << request << std::endl;} else if (successor != nullptr) {successor->handleRequest(request);}}
};// 具体处理者 B
class ConcreteHandlerB : public Handler {
public:void handleRequest(int request) override {if (request >= 10 && request < 20) {std::cout << "ConcreteHandlerB handled request " << request << std::endl;} else if (successor != nullptr) {successor->handleRequest(request);}}
};// 客户端
int main() {Handler* handlerA = new ConcreteHandlerA();Handler* handlerB = new ConcreteHandlerB();handlerA->setSuccessor(handlerB);handlerA->handleRequest(5);  // 应由 ConcreteHandlerA 处理handlerA->handleRequest(15); // 应由 ConcreteHandlerB 处理handlerA->handleRequest(25); // 没有处理者可以处理delete handlerA;delete handlerB;return 0;
}
Python 代码案例
# 抽象处理者
class Handler:def __init__(self):self.successor = Nonedef set_successor(self, successor):self.successor = successordef handle_request(self, request):pass# 具体处理者 A
class ConcreteHandlerA(Handler):def handle_request(self, request):if 0 <= request < 10:print(f"ConcreteHandlerA handled request {request}")elif self.successor is not None:self.successor.handle_request(request)# 具体处理者 B
class ConcreteHandlerB(Handler):def handle_request(self, request):if 10 <= request < 20:print(f"ConcreteHandlerB handled request {request}")elif self.successor is not None:self.successor.handle_request(request)# 客户端
if __name__ == "__main__":handlerA = ConcreteHandlerA()handlerB = ConcreteHandlerB()handlerA.set_successor(handlerB)handlerA.handle_request(5)  # 应由 ConcreteHandlerA 处理handlerA.handle_request(15) # 应由 ConcreteHandlerB 处理handlerA.handle_request(25) # 没有处理者可以处理
Go 代码案例
package mainimport ("fmt"
)// 抽象处理者
type Handler interface {setSuccessor(successor Handler)handleRequest(request int)
}// 具体处理者 A
type ConcreteHandlerA struct {successor Handler
}func (h *ConcreteHandlerA) setSuccessor(successor Handler) {h.successor = successor
}func (h *ConcreteHandlerA) handleRequest(request int) {if request >= 0 && request < 10 {fmt.Printf("ConcreteHandlerA handled request %d\n", request)} else if h.successor != nil {h.successor.handleRequest(request)}
}// 具体处理者 B
type ConcreteHandlerB struct {successor Handler
}func (h *ConcreteHandlerB) setSuccessor(successor Handler) {h.successor = successor
}func (h *ConcreteHandlerB) handleRequest(request int) {if request >= 10 && request < 20 {fmt.Printf("ConcreteHandlerB handled request %d\n", request)} else if h.successor != nil {h.successor.handleRequest(request)}
}// 客户端
func main() {handlerA := &ConcreteHandlerA{}handlerB := &ConcreteHandlerB{}handlerA.setSuccessor(handlerB)handlerA.handleRequest(5)  // 应由 ConcreteHandlerA 处理handlerA.handleRequest(15) // 应由 ConcreteHandlerB 处理handlerA.handleRequest(25) // 没有处理者可以处理
}

4. 总结

责任链模式 是一种行为设计模式,它允许你将请求沿着处理者链进行发送。每个处理者都可以处理请求,或者将其传递给链上的下一个处理者。这种模式使得多个对象都有机会处理请求,而无需提前指定具体的处理者。通过这种方式,可以减少请求发送者和接收者之间的耦合。

主要优点
  1. 解耦:请求的发送者和接收者之间没有直接的耦合关系,提高了系统的灵活性。
  2. 增强可扩展性:可以动态地增加或改变处理者的数量和顺序,而不会影响客户端。
  3. 支持多个处理者:多个处理者可以依次处理同一个请求,增加了系统的灵活性和可配置性。
主要缺点
  1. 调试困难:由于请求的处理过程是动态的,调试时可能难以跟踪请求的处理路径。
  2. 性能开销:如果链过长,可能会导致性能下降,尤其是在每个处理者都需要执行某些操作时。
适用场景
  • 当一个请求需要被多个对象中的一个或多个处理时。
  • 当处理者的选择需要在运行时动态决定时。
  • 当需要在不明确指定接收者的情况下,向多个对象中的一个发送请求时。
  • 当需要创建一个可灵活配置的处理流程时。

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

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

相关文章

大数据技术之Spark :我快呀~

在 MapReduce 为海量数据的计算服务多年后&#xff0c;随着时代的发展和 Spark 等新技术的出现&#xff0c;它的劣势也慢慢的凸显出来了&#xff1a; 执行速度慢。编程复杂度过高。 先看第一点 2000 年代诞生的 MapReduce &#xff0c;因为计算资源有限&#xff0c;所以 Map…

新160个crackme - 105-royalaccezzcrackme

运行分析 需破解Name和Serial&#xff0c;点击OK没反应 PE分析 ASM程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida找到关键字符串 进行静态分析&#xff0c;逻辑如下&#xff1a;1、Name长度大于4&#xff0c;小于212、fun_1返回值为1 对func_1进行动态调试分…

【RISC-V CPU 专栏 -- 香山处理器介绍】

文章目录 RISC-V 香山处理器介绍雁栖湖处理器南湖处理器RISC-V 香山处理器介绍 相信很多小伙伴对于“香山”都不陌生,它是一款开源RISC-V处理器核,香山的每一代架构,都是采用了湖的名字,第一代架构被命名为雁栖湖,第二代架构则叫做 “南湖”。 “雁栖湖”这款处理器的 R…

远程视频验证如何改变商业安全

如今&#xff0c;商业企业面临着无数的安全挑战。尽管企业的形态和规模各不相同——从餐厅、店面和办公楼到工业地产和购物中心——但诸如入室盗窃、盗窃、破坏和人身攻击等威胁让安全主管时刻保持警惕。 虽然传统的监控摄像头网络帮助组织扩大了其态势感知能力&#xff0c;但…

【TQ2440】02 串口连接进入u-boot

需要收到的板子已经烧写好系统或u-boot&#xff0c;看开机液晶屏底下的四个LED灯有没有亮黄绿色&#xff0c;没有就是还没烧写u-boot&#xff0c;需要先使用Jlink烧写u-boot 进入 uboot 的下载模式&#xff0c;如果从 Nor Flash 启动默认的就是进入 uboot 的下载模式&#xff…

QCommandLinkButton控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…

【Vue】Ego商城项目跟做

技术栈 Vue全家桶&#xff1a;Vue VueRouter Vuex Axios ElementUI 依赖安装 网络请求&#xff1a;npm install --save axios --no-fund Element&#xff1a;vue add element 后端相关依赖&#xff1a;npm install --save express cors mysql --no-fund token&#xff1a;np…

python简单算法

冒泡 def boll(lis):i 0while i<len(lis)-1:j 0while j<len(lis)-1-i:if lis[j] > lis[j1]:lis[j],lis[j 1] lis[j1],lis[j]j1i1选择排序 def selct1(lit):i 0while i<len(lit)-1:j i1min1 iwhile j < len(lit):if lit[j] < lit[min1]:min1 jj 1li…

2024年第15届蓝桥杯C/C++组蓝桥杯JAVA实现

目录 第一题握手&#xff0c;这个直接从49累加到7即可&#xff0c;没啥难度&#xff0c;后面7个不握手就好了&#xff0c;没啥讲的&#xff0c;(然后第二个题填空好难&#xff0c;嘻嘻不会&#xff09; 第三题.好数​编辑 第四题0R格式 宝石组合 数字接龙 最后一题:拔河 第…

【Docker】常用命令汇总

Docker 是1个开源的应用容器引擎&#xff0c;基于Go 语言并遵从 Apache2.0 协议开源。 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱机制&#xff0c;相…

如何选择最适合企业的ETL解决方案?

在今天的大数据时代&#xff0c;企业的数据管理和处理变得愈发重要。企业也越来越依赖于数据仓库和数据湖来提取、转换和加载&#xff08;ETL&#xff09;关键业务信息。一个高效、灵活的ETL解决方案不仅能提升数据处理能力&#xff0c;还能为企业决策提供有力支持。然而&#…

EG3D: Efficient Geometry-aware 3D Generative Adversarial Networks 学习笔记

1 Contributions 混合显式-隐式网络架构&#xff1a;提出了一种 Tri-plane 的3D表征方法&#xff0c;结合显式体素网格与隐式解码器的优点 速度快&#xff0c;内存效率高&#xff1b; 支持高分辨率生成&#xff0c;保持3D表征的灵活性和表达能力。与纯显式或隐式方法相比&#…

第十六届蓝桥杯模拟赛(第一期)-Python

本次模拟赛我认为涉及到的知识点&#xff1a; 分解质因数 Python的datetime库 位运算 简单dp 1、填空题 【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结…

ubuntu 安装 docker 记录

本文假设系统为 Ubuntu&#xff0c;从 16.04 到 24.04&#xff0c;且通过 APT 命令安装。理论上也其他 Debian 系的操作系统。 WSL 也一样。 感觉 Docker 官方在强推 Docker Desktop&#xff0c;搜索 Docker 安装文档&#xff0c;一不小心就被导航到了 Docker Desktop 的安装页…

太速科技-512-基于ZU19EG的4路100G 8路40G的光纤汇流计算卡

基于ZU19EG的4路100G 8路40G的光纤汇流计算卡 一、板卡概述 本板卡系我司自主设计研发&#xff0c;基于Xilinx公司Zynq UltraScale MPSOC系列SOC XCZU19EG-FFVC1760架构&#xff0c;ARM端搭载一组64-bit DDR4&#xff0c;总容量达4GB&#xff0c;可稳定运行在2400MT/s…

C#基础56-60

56.字符数组x中存有任意一串字符&#xff1b;串中的所有小写字母改写成大写字母&#xff0c;如果是大写字母改为小写字母&#xff0c;其他字符不变。最后把已处理的字符串仍重新存入字符数组x中&#xff0c;最后调用函数把结果输出到控制台中。 57.求出100以上1000以内所有个位…

计算机网络:应用层知识点概述及习题

网课资源&#xff1a; 湖科大教书匠 1、概述 习题1 1 在计算机网络体系结构中&#xff0c;应用层的主要功能是 A. 实现进程之间基于网络的通信 B. 通过进程之间的交互来实现特定网络应用 C. 实现分组在多个网络上传输 D. 透明传输比特流 2 以下不属于TCP/IP体系结构应用层范畴…

深入浅出摸透AIGC文生图产品SD(Stable Diffusion)

hihi,朋友们,时隔半年(24年11月),终于能腾出时间唠一唠SD了🤣,真怕再不唠一唠,就轮不到SD了,技术更新换代是在是太快! 朋友们,最近(24年2月)是真的没时间整理笔记,每天都在疯狂的学习Stable Diffusion和WebUI & ComfyUI,工作实在有点忙,实践期间在飞书上…

uniapp+vue2+uview2.0导航栏组件二次封装

样式 代码 <template><view class"navBar"><u-navbar :title"title" :titleColor"titleColor" :bgColor"bgColor" :safeAreaInsetTop"safeAreaInsetTop":autoBack"true" leftClick"leftClic…

【Git】常用命令汇总

目录 一.安装及配置 1.在 Windows 上安装 2.用户信息 3.差异分析工具 二.基础 1.创建仓库 2.提交与修改 三.分支管理 1.创建分支 2.合并分支 四.远程操作 1.管理 Git 仓库中的远程仓库 2.数据的获取与推送 五.标签 1.创建轻量标签和附注标签 2.查看标签和标签信…