设计模式使用场景实现示例及优缺点(行为型模式——责任链模式)
在一个遥远的森林深处,有一个和谐的动物王国。这个王国里的动物们都有各自的职责,大家相互合作,共同维护着森林的和平与繁荣。
一天,森林里来了一只迷路的小兔子,她焦急地四处张望,不知道该怎么办。于是,小兔子决定去找森林之王——狮子大王寻求帮助。
小兔子一路奔跑,终于来到狮子大王的洞穴。她小心翼翼地走进去,对狮子大王说道:“尊敬的狮子大王,我迷路了,能不能请您帮我找到回家的路?”
狮子大王温和地笑了笑,说道:“小兔子,我的职责是保护森林的安全,而不是导游。但别担心,我会帮你找到最合适的动物来帮你。请跟我来。”
于是,狮子大王带着小兔子来到了一条宽敞的森林小道上,他对小兔子说:“在我们动物王国中,每个动物都有各自的职责,我们通过责任链来处理各种请求。你跟着这条小道走下去,每遇到一个动物,就告诉它你的请求,直到有一个动物能够帮你。”
小兔子点点头,开始沿着小道前行。她第一个遇到的是聪明的猫头鹰。
“小兔子,你有什么需要帮助的吗?”猫头鹰问道。
“猫头鹰先生,我迷路了,您能帮我找到回家的路吗?”小兔子问。
猫头鹰摇摇头,说:“我负责在夜晚守护森林,指引方向不是我的职责。不过,你可以继续往前走,去找长颈鹿大姐,她或许能帮你。”
小兔子继续前行,终于见到了长颈鹿大姐。她仰起头问道:“长颈鹿大姐,您能帮我找到回家的路吗?”
长颈鹿大姐低下头,温柔地说道:“小兔子,我的职责是帮助大家摘取高处的果实。不过别担心,你继续走下去,去找松鼠先生,他一定能帮到你。”
小兔子谢过长颈鹿大姐,继续沿着小道走。终于,她遇到了松鼠先生。松鼠先生正忙着整理他的坚果储备。
“小兔子,有什么我可以帮你的吗?”松鼠先生热情地问道。
“松鼠先生,我迷路了,您能帮我找到回家的路吗?”小兔子问。
松鼠先生开心地跳起来,说道:“这正是我的职责之一!我经常在森林中奔跑,对这里的每一条小路都非常熟悉。跟我来,我带你回家!”
于是,松鼠先生带着小兔子穿过树林,顺利找到了回家的路。小兔子感激地道谢,并开心地回到了自己的家。
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为设计模式,允许对象将请求沿着处理器链传递,直到一个处理器决定处理该请求为止。这种模式的核心在于解耦发送者和接收者之间的关系,通过多个对象共同处理一个请求,从而避免将一个请求的发送者和接收者耦合在一起。
核心组件
- Handler(处理器):定义了处理请求的接口,并可实现后继链。
- ConcreteHandler(具体处理器):具体处理器实现处理请求的接口,如果该处理器不能处理请求,则将其传递给链中的下一个处理器。
- Client(客户端):通常构造链并向链的首个处理器发送请求。
适用场景
- 当有多个对象可以处理一个请求,而发送者不需要明确知道哪一个对象将会处理该请求时:
- 责任链模式使得请求的发送者和接收者解耦。
- 当需要动态指定一组对象处理请求时:
- 可以动态地增加或修改处理链。
- 当处理请求的顺序重要时:
- 可以控制请求在链中的传递顺序。
实现实例
以客户支持系统为例,不同级别的支持人员处理不同级别的客户请求。
处理器接口(Handler Interface)
Handler
类是一个抽象类,定义了处理请求的方法 handleRequest()
和设置后继处理器的方法 setSuccessor()
。
public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(Request request);
}
handleRequest(Request request)
方法用于处理请求,每个具体处理器根据具体条件决定是否处理请求。setSuccessor(Handler successor)
方法用于设置当前处理器的后继处理器,以构建责任链。
具体处理器(Concrete Handler)
具体处理器类继承自 Handler
类,根据特定条件判断是否能够处理请求,如果不能则传递给后继者。
ConcreteHandler1
public class ConcreteHandler1 extends Handler {public void handleRequest(Request request) {if (request.getValue() < 10) { // 判断条件:处理值小于10的请求System.out.println("ConcreteHandler1 handled request " + request.getValue());} else if (successor != null) {successor.handleRequest(request); // 如果无法处理,则传递给后继者}}
}
ConcreteHandler2
public class ConcreteHandler2 extends Handler {public void handleRequest(Request request) {if (request.getValue() >= 10 && request.getValue() < 20) { // 判断条件:处理值在10到20之间的请求System.out.println("ConcreteHandler2 handled request " + request.getValue());} else if (successor != null) {successor.handleRequest(request); // 如果无法处理,则传递给后继者}}
}
客户端代码(Client Code)
客户端代码创建具体处理器实例,并构建责任链,然后发起请求。
public class Client {public static void main(String[] args) {Handler h1 = new ConcreteHandler1();Handler h2 = new ConcreteHandler2();h1.setSuccessor(h2); // 设置责任链Request request = new Request(15); // 创建请求h1.handleRequest(request); // 开始处理请求}
}
在客户端代码中,首先创建了两个具体处理器实例 ConcreteHandler1
和 ConcreteHandler2
,然后通过 setSuccessor()
方法将它们连接起来形成责任链。最后创建一个请求对象并调用第一个处理器的 handleRequest()
方法开始处理请求。
责任链模式允许请求在多个对象之间传递,直到找到合适的处理器为止。这种设计方式使得系统更加灵活和可扩展,每个处理器可以独立变化而不影响整个处理流程。
优缺点
优点
- 降低耦合度:
- 责任链模式使得一个请求的发送者和接收者之间不必有明确的联系。
- 增加了请求处理对象的灵活性:
- 可以动态地添加或修改处理链。
缺点
- 请求可能不被处理:
- 如果没有任何处理器处理请求,它可能会在链的末端被丢弃。
- 性能问题:
- 在某些情况下,请求在链中的传递可能会导致延迟。
类图
+----------------+ +------------------+
| Handler |---------> | ConcreteHandler|
+----------------+ +------------------+
| + handleRequest() | + handleRequest()|
| + setSuccessor() | |
+----------------+ +------------------+
| | |
+----------------+ ||+-------------------+--------+----------------+| | | |
+----------------+ +----------------+ +----------------+ +--------------+
|Handler1 | |ConcreteHandler1| |ConcreteHandler2| | ... |
+----------------+ +----------------+ +----------------+ +--------------+
| + handleRequest()| | + handleRequest()| | + handleRequest()| | + handleRequest()|
+----------------+ +----------------+ +----------------+ +--------------+
总结
责任链模式提供了一种将请求沿着一条链进行传递的机制,通过这种方式可以解耦请求的发送者和接收者。这种模式特别适用于有多个对象可能处理同一个请求时,允许请求沿链传递直到一个对象处理它为止。
相关文章:
设计模式使用场景实现示例及优缺点(行为型模式——责任链模式)
在一个遥远的森林深处,有一个和谐的动物王国。这个王国里的动物们都有各自的职责,大家相互合作,共同维护着森林的和平与繁荣。 一天,森林里来了一只迷路的小兔子,她焦急地四处张望,不知道该怎么办。于是&am…...
CSS-1_0 CSS和文档流
文章目录 CSS和文档流如何证明这个流的存在呢?流和display番外:inline-block 碎碎念 CSS和文档流 首先什么叫流呢? 通常来说,我们最终看到的网页是HTML文档中定义的各个元素挨个输出的结果,这种一个接一个输出的方式…...
小程序图片下载保存方法,图片源文件保存!
引言 现在很多时候我们在观看到小程序中的图片的时候,想保存图片的原文件格式的话,很多小程序是禁止保存的,即使是让保存的话,很多小程序也会限制不让保存原文件,只让保存一些分辨率很低的,非常模糊的图片…...
新书速览|深入理解Hive:从基础到高阶:视频教学版
《深入理解Hive:从基础到高阶:视频教学版》 本书内容 《深入理解Hive:从基础到高阶:视频教学版》采用“理论实战”的形式编写,通过大量的实例,结合作者多年一线开发实战经验,全面地介绍Hive的使用方法。《深入理解Hiv…...
钡铼Profinet、EtherCAT、Modbus、MQTT、Ethernet/IP、OPC UA分布式IO系统BL20X系列耦合器
BL20X系列耦合器是钡铼技术开发的一款用于分布式I/O系统的设备,专为工业环境下的高速数据传输和远程设备控制而设计,支持多种工业以太网协议,包括Profinet、EtherCAT、Modbus、MQTT、Ethernet/IP和OPC UA等。如果您正在考虑部署BL20X系列耦合…...
Git分支合并以及分支部分合并 提交记录合并
Git分支合并,以及分支部分合并,提交记录合并 最近工作中用到git分支合并的场景,记录一下. 分支整体合并,合并所有记录 仅合并分支部分代码...
IDEA关联数据库
《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试(Debug) 第七章 …...
【Leetcode】14. 最长公共前缀
leetcode原地址:https://leetcode.cn/problems/longest-common-prefix 描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。 示例 1: 输入:strs [“flower”,“flow”,“flight”…...
【BUG】已解决:zipfile.BadZipFile: File is not a zip file
已解决:zipfile.BadZipFile: File is not a zip file 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于医疗科技公司,热衷分享知识,武汉城市开发…...
小白新手搭建个人网盘
小白新手搭建个人网盘 序云服务器ECS重置密码远程连接ECS实例 安装OwnCloud安装Apache服务PHP运行环境NAS挂载挂载验证操作体验 序 阿里云文件存储NAS(Apsara File Storage NAS)是一个可大规模共享访问,弹性扩展的分布式文件系统。本文主要是…...
NineData全面支持PostgreSQL可视化表结构设计
“PostgreSQL 是最像 Oracle 的开源关系型数据库“,也正因为如此,很多企业都青睐 PostgreSQL,拿它当成 Oracle 的替代品。所以毫无疑问,目前 PostgreSQL 在企业中非常常见。 对于直接接触 PostgreSQL 的开发人员而言,…...
从系统层面认识Linux及mysql中的多表查询
为什么计算机起始时间是1970年1月1日 为什么计算机起始时间是1970年1月1日-CSDN博客https://blog.csdn.net/csdn_kou/article/details/81535452 date "%Y-%m-%d %H:%M:%S" 查看日期 sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 在数据层面 CPU不…...
PCB(印制电路板)制造涉及的常规设备
印制电路板(PCB)的制造涉及多种设备和工艺。从设计、制作原型到批量生产,每个阶段都需要不同的专业设备。以下是一些在PCB制造过程中常见的设备: 1. 计算机辅助设计(CAD)软件: - 用于设计PC…...
《Windows API每日一练》10.3 公用对话框
Windows最初发行时的主要目标之一就是提倡一种标准化的用户界面。对于公用菜单 项来说,这一目标实现得很快。几乎所有的软件制造商都采用了Alt-File-Open组合来打开 文件。但是,真正用来打开文件的对话框却经常很不一样。 从Windows 3.1开始,…...
C++中的引用
在C中,我们要学习一个新的概念,叫做引用。引用不是对象,它只是给变量取一个别名。就好比,我们每个人总会右一下外号,或者是小名。当朋友或者家长不管是直接叫你的名字,还是叫你的小名,你都会答应…...
【自学安全防御】三、企业双机热备和带宽管理的综合实验
实验拓扑: 实验任务: 12,对现有网络进行改造升级,将当个防火墙组网改成双机热备的组网形式,做负载分担模式,游客区和DMZ区走FW3,生产区和办公区的流量走FW1 13,办公区上网用户限制流…...
无极与有极电容的区别
无极性电容与有极性电容:差异与应用探索 在电子元件的广阔世界里,电容器无疑是不可或缺的一部分。它们以储存电荷和调节电路中的电压与电流而闻名。然而,电容器并非一概而论,其中最为显著的区别之一就是无极性电容与有极性电容。…...
入坑树莓派(2)——树莓派4B与手机蓝牙通信
入坑树莓派(2)——树莓派4B与手机蓝牙通信 1、引言 在入坑树莓派(1)中已经搞掂了可视化问题。现在继续开展下一步,尝试与手机通信,一开始是想弄wifi连接的,但发现基于wifi的APP比较难弄,为了降低开发的难度,又因为树莓派板子自带蓝牙模块,所以直接选用蓝牙连接手机…...
RocketMQ单结点安装/Dashboard安装
目录 1.安装NameServer 2.安装Broker 3.使用自带工具测试数据发送 4.使用DashBoard进行查看 5.关闭相关设备 前置条件:两台虚拟机CentOS Linux release 7.5.1804(ps:当然也可以都部署在一台机器上) RocketMq属于天生集群。需要同时启动nameServer和Broker进行…...
【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第二篇 Linux系统编程篇-第三十四章 进程基础
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...
使用LVS+NGinx+Netty实现数据接入
数据接入 链接参考文档 LVSKeepalived项目 车辆数据上收,TBox通过TCP协议连接到TSP平台 建立连接后进行数据上传。也可借由该连接实现远程控制等操作。 通过搭建 LV—NGinx—Netty实现高并发数据接入 LVS:四层负载均衡(位于内核层&#x…...
云手机结合自主ADB命令接口 提升海外营销效率
现在,跨境电商直播已经成为在线零售的重要渠道,在大环境下,确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口,为电商直播营销提供了技术支持,使得应用开发、测试、优化和运维更加高效。 什么是A…...
【计算机视觉前沿研究 热点 顶会】CVPR 2024中与域适应、分布外目标检测相关的论文
测试时间线性分布外检测 分布外( OOD)检测旨在通过在输入样本显著偏离训练分布(分布中)时触发警报来解决神经网络的过度置信度预测,这表明输出可能不可靠。当前的 OOD 检测方法探索各种线索来识别 OOD 数据࿰…...
首次由国产8K摄像机服务巴黎奥运会8K公用信号
法国巴黎时间16日上午,中央广播电视总台“中国红”8K转播车穿越大半个地球,抵达法兰西体育场,顺利完成与奥林匹克转播公司(OBS)的交接。 (1)“中国红”8K转播车 作为适合户外露天项目的“移动制作域”,“…...
idea怎么配置gradle多个版本
1.背景 gradle版本很多,而且很多时候版本是不兼容的,我们希望拉取下来的代码就包含已经配置好的版本,而不是去配置本机的gradle版本..... 意思就是要实现项目A可以用6.X版本 项目B可以使用7.X版本 项目C可以用9.X版本..... 2.配置方式 步骤一:项目根路径下保留一个文件夹…...
SpringCloudAlibaba-Seata2.0.0与Nacos2.2.1
一、下载 ## 下载seata wget https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.tar.gz## 解压 tar zxvf seata-server-2.0.0.tar.gz二、执行sql文件 ## 取出sql文件执行 cd /seata/script/server/db/mysql ## 找个mysql数据库执行三、…...
【编程语言】C++和C的异同点
文章目录 相同点不同点cin和scanf()结构体struct指针:NULL、nullptr、void* 有一段时间没有发博客了,从笔记里摘录一些发两篇。 相同点 C有很多从C继承过来的东西,因此C书(《C Primer》、《C Primer Plus》)中有一些基础的东西讲的并没有C书…...
【日常记录】【插件】excel.js导出的时候给单元格设置下拉选择、数据校验等
文章目录 1. 代码基本结构2. 导出的excel 某单元格的值设置为下拉选择3. 如何把下拉选择项设置为动态4. 单元格设置校验、提示5. 在WPS上的设置 1. 代码基本结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><…...
分布式 I/O 系统Modbus TCP 耦合器BL200
BL200 耦合器是一个数据采集和控制系统,基于强大的 32 位微处理器设计,采用 Linux 操作系统,可以快速接入现场 PLC、SCADA 以及 ERP 系统, 内置逻辑控制、边缘计算应用,支持标准 Modbus TCP 服务器通讯,以太…...
人工智能导论-机器学习
机器学习概述 概述 本章主要介绍的机器学习的概念、发展历程、发展趋势、相关应用,着重拓展机监督学习和无监督学习的相关知识。 重点:机器学习的定义和应用; 难点:机器学习算法及分类。 机器学习 - 重要性 MachineLeaning出…...
wordpress增加访问速度/百度资源共享
VMware ThinApp可以实现在同一操作系统上运行任何版本的虚拟应用程序而不发生冲突,你甚至可以运行同一应用程序的多个版本。将VMware ThinApp应用到现在的基础管理设施上,并加快您的软件开发和桌面部署吧,通过无代理的应用程序虚拟化技术让应…...
1个服务器可以做多少个网站/线上推广的优势和好处
嵌入式开发需要一定的知识和技能储备。下面列出技能树,后续章节再一一说明。 编程语言编程语言肯定是要的,这里只讲了编程语言的语法。但是你以为只要掌握C语言就够了?太天真了,Makefile 编译肯定要的呀。Kconfig 内核也要配置的呀…...
建网站公司是如何赚钱/成人短期电脑培训班学费
在C中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符: 1、插入器(<<) 向流输出数据。比如说系统有一个默认的标准输出流(cout),一…...
权威的南昌网站设计/口碑营销
约瑟夫环进阶: 2020个数 围成一个圈,从第一个开始,每过三个,删除三个,例:从1开始,删除2,3,4。求出最后剩下的数是多少? 代码如下: public static void main…...
wordpress seo 介绍/品牌推广方式
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWidth (包括边线的宽) 网页可见区域高:document.body.offsetHeight (包括边线的宽) 网页正文全文宽&a…...
网站正在建设中单页/重庆seo推广外包
13.3.2 cocos2d项目如何支持ARCiOS 5中所支持的全新特性ARC(Automatic Reference Counting)首次在iOS系统中提供了自动内存管理,从而避免因为对retain、release、autorelease这些命令的错误调用而导致内存泄漏。实际上,Apple还成功…...