【重温设计模式】职责链模式及其Java示例

职责链模式的介绍

在开发过程中,我们经常会遇到这样的问题:一个请求需要经过多个对象的处理,但是我们并不知道具体由哪个对象来处理,或者说,我们希望由接收到请求的对象自己去决定如何处理或者是将请求传递给下一个对象处理。这种情况下,我们可以使用一种被称为"职责链模式"的设计模式来解决这个问题。

职责链模式,也被称为链式处理模式,它是一种行为型设计模式,其主要思想是让多个对象都有机会处理请求,从而解耦了请求的发送者和接收者。在这个模式中,请求会从链条的一端开始,沿着链条逐个传递,直到有一个对象处理它为止。这种模式在软件开发中的应用场景非常广泛,比如在Java的Servlet中,当一个http请求到达服务器时,它可能需要经过多个Filter的处理,这种场景就可以使用职责链模式来实现。

Java中的职责链模式实例

在我们了解了职责链模式的基本概念和应用场景后,接下来,我们将通过一个具体的Java实例,展示如何在实际开发中使用职责链模式,以及如何通过职责链模式解决实际问题。

假设我们正在开发一个处理用户请求的系统,每个请求都有一个处理级别。我们有三个处理器,他们分别处理不同级别的请求。我们可以使用职责链模式来处理这个问题。首先,我们需要定义一个处理器类,这个类有一个处理请求的方法和一个设置下一个处理器的方法。下面是处理器类的代码:

public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(int requestLevel);
}

然后,我们可以定义三个具体的处理器类,它们都继承自处理器类:

public class HandlerOne extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 1) {System.out.println("HandlerOne has handled the request.");} else if (successor != null) {successor.handleRequest(requestLevel);}}
}public class HandlerTwo extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 2) {System.out.println("HandlerTwo has handled the request.");} else if (successor != null) {successor.handleRequest(requestLevel);}}
}public class HandlerThree extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 3) {System.out.println("HandlerThree has handled the request.");} else {System.out.println("No handler can handle the request.");}}
}

最后,我们可以在主函数中创建处理器对象,并设置它们的职责链:

public class OneMore {public static void main(String[] args) {HandlerOne handlerOne = new HandlerOne();HandlerTwo handlerTwo = new HandlerTwo();HandlerThree handlerThree = new HandlerThree();handlerOne.setSuccessor(handlerTwo);handlerTwo.setSuccessor(handlerThree);handlerOne.handleRequest(2);}
}

这样,当我们有一个请求时,我们只需要将请求传递给链条的第一个处理器,它会根据请求的级别来决定是自己处理还是传递给下一个处理器。这就是职责链模式的基本用法。

在这个例子中,我们可以看到,职责链模式可以很好地将请求的发送者和接收者解耦,使得请求的发送者不需要知道请求的接收者是谁,请求的接收者也不需要知道请求的发送者是谁。这样,我们就可以灵活地改变处理器的组合和顺序,而不会影响到请求的发送者。

然而,职责链模式并不是万能的。接下来,我们将探讨职责链模式的优缺点,以及在何种情况下使用职责链模式是合适的,以及在何种情况下不建议使用。

职责链模式的优缺点

职责链模式的一个显著优点是它可以降低对象之间的耦合度。在职责链模式中,一个请求可以被任何处理请求的对象处理,这样,发送者和接收者的耦合度就被降低了。它也支持动态的添加或者删除责任对象,可以在运行时改变链中的成员或者调整它们的顺序,这提供了很高的灵活性。此外,职责链模式还可以控制请求的处理过程,请求者不必知道请求在何时、如何、被谁处理,只需将请求发送到链上即可。

然而,职责链模式也有其不足之处。首先,它不能保证每个请求都会被处理,如果所有的处理对象都不处理请求,那么请求就会被丢弃。此外,如果责任链过长,请求的处理可能会涉及多个处理对象,这将导致系统性能的降低。因此,使用职责链模式时,需要慎重考虑如何定义和组织责任链。

那么,在何种情况下使用职责链模式是合适的呢?当一个系统的功能分解成多个处理对象,且这些对象有明确的顺序关系时,可以考虑使用职责链模式。例如,一个订单处理系统,订单的处理流程可能包括订单校验、库存检查、支付处理等步骤,这些步骤就可以组成一个责任链。

反之,在何种情况下不建议使用职责链模式呢?如果一个系统的功能不能分解为多个处理对象,或者处理对象之间没有明确的顺序关系,那么使用职责链模式可能会引入不必要的复杂性。例如,一个简单的数据查询系统,数据的查询并不需要经过多个处理步骤,此时使用职责链模式可能会让系统变得复杂。

总结

职责链模式是一种强大而灵活的设计模式,它可以帮助我们设计出解耦度高、可扩展性强的系统。然而,这并不意味着我们应该在所有情况下都使用职责链模式。在使用任何设计模式时,我们都应该充分理解其优缺点,以及适用和不适用的情况,然后根据实际的需求和情况来做出合理的选择。

在这个过程中,我们应该始终记住,设计模式只是工具,而不是目标。我们的目标是设计出高质量的软件,而设计模式只是帮助我们达到这个目标的手段。我们应该根据实际的需求和情况,灵活地使用和组合各种设计模式,而不是盲目地追求使用某种设计模式。

总的来说,职责链模式是一种有用的设计模式,它可以帮助我们解决一些特定的设计问题。然而,无论是使用职责链模式,还是其他的设计模式,我们都应该以实际的需求为出发点,以提高软件的质量为目标,灵活地使用和组合各种设计模式,以实现最佳的设计。

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

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

相关文章

【深度学习笔记】计算机视觉——锚框

锚框 目标检测算法通常会在输入图像中采样大量的区域&#xff0c;然后判断这些区域中是否包含我们感兴趣的目标&#xff0c;并调整区域边界从而更准确地预测目标的真实边界框&#xff08;ground-truth bounding box&#xff09;。 不同的模型使用的区域采样方法可能不同。 这里…

吴恩达deeplearning.ai:正则化对于偏方差的影响制定用于性能评估的基准

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 这节我们看看正则化系数 文章目录 以线性回归为例交叉验证误差对于确定 λ \lambda λ的作用 指定用于性能评估的基准语音识别的例子 以线性回归为例 让我们举一个例子&#xff1a; 模型&am…

Outlook邮箱IMAP密码怎么填写?账户设置?

Outlook邮箱IMAP密码是什么&#xff1f;Outlook如何设置IMAP&#xff1f; 许多用户会选择通过IMAP协议将邮箱与各种邮件客户端进行连接。而在设置过程中&#xff0c;填写IMAP密码是必不可少的一步。那么&#xff0c;Outlook邮箱的IMAP密码应该如何填写呢&#xff1f;接下来&am…

【Linux】深入理解ls命令

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 基本用法 常用选项 示例 高级用法 结语 我的其他博客 前言 在 Linux 系统中&#xff0c;ls 命令是一个强大而又基础的工具&am…

高刷显示器 - HKC VG253KM

&#x1f525;&#x1f525; 今天来给大家揭秘一款电竞神器 - HKC VG253KM 高刷电竞显示器&#xff01;这款显示器可是有着雄鹰展翅般的设计灵感&#xff0c;背后的大鹏展翅鹰翼图腾让人过目难忘。那么&#xff0c;这款显示器到底有哪些过人之处呢&#xff1f;一起来看看吧&…

【MySQL】基于Docker搭建MySQL一主二从集群

本文记录了搭建mysql一主二从集群&#xff0c;这样的一个集群master为可读写&#xff0c;slave为只读。过程中使用了docker&#xff0c;便于快速搭建单体mysql。 1&#xff0c;准备docker docker的安装可以参考之前基于yum安装docker的文章[1]。 容器相关命令[2]。 查看正在…

Pod和容器设计模式

为什么需要 Pod&#xff1b; Pod 的实现机制&#xff1b; 详解容器设计模式。 一、为什么需要 Pod 容器的基本概念 现在来看第一个问题&#xff1a;为什么需要 Pod&#xff1f;我们知道 Pod 是 Kubernetes 项目里面一个非常重要的概念&#xff0c;也是非常重要的一个原子调…

144. 二叉树的前序遍历

给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root [1] 输出&am…

SpringCloud(18)之Sleuth +Zipkin链路追踪

一、Zipkin介绍 Zipkin是一个开放源代码分布式的跟踪系统&#xff0c;它可以帮助收集服务的时间数据&#xff0c;以解决微服务架构中的延迟问 题&#xff0c;包括数据的收集、存储、查找和展现。每个服务向zipkin报告计时数据&#xff0c;zipkin会根据调用关系通 过Zipkin UI…

1.2 在卷积神经网络中,如何计算各层感受野的大小

1.2 在卷积神经网络中&#xff0c;如何计算各层感受野的大小 分析与解答&#xff1a; 在卷积神经网络中&#xff0c;由于卷积的局部连接性&#xff0c;输出特征图上的每个节点的取值&#xff0c;是由卷积核在输入特征图对应位置的局部区域内进行卷积而得到的&#xff0c;因此这…

【笔试强训错题选择题】Day5.习题(错题)解析

文章目录 前言 错题题目 错题解析 总结 前言 错题题目 1. ​ ​ 2. 3. ​ 4. ​ 5. ​ 错题解析 1. 移位运算符的使用 2. 3. 4. 5. 总结

如何用TCC实现分布式事务?

TCC事务介绍 TCC&#xff08;Try-Confirm-Cancel&#xff09;是除可靠消息队列以外的另一种常见的分布式事务机制&#xff0c;它是由数据库专家帕特 赫兰德&#xff08;Pat Helland&#xff09;在2007年撰写的论文《Life beyond Distributed Transactions: An Apostate’s Op…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的体育赛事目标检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发和研究体育赛事目标检测系统对于增强体育分析和观赏体验至关重要。本篇博客详细讲述了如何运用深度学习技术构建一个体育赛事目标检测系统&#xff0c;并提供了完整的实现代码。系统基于先进的YOLOv8算法&#xff0c;对比了YOLOv7、YOLOv6、YOLOv5的性能&a…

爬虫入门到精通_实战篇7(Requests+正则表达式爬取猫眼电影)_ 抓取单页内容,正则表达式分析,保存至文件,开启循环及多线程

1 目标 猫眼榜单TOP100&#xff1a;https://www.maoyan.com/board 2 流程框架 抓取单页内容&#xff1a;利用requests请求目标站点&#xff0c;得到单个网页HTML代码&#xff0c;返回结果。正则表达式分析&#xff1a;根据HTML代码分析得到电影名称,主演,上映时间,评分,图片…

C语言中的分支和循环语句:从入门到精通

分支和循环语句 1. 前言2. 预备知识2.1 getchar函数2.2 putchar函数2.3 计算数组的元素个数2.4 清屏2.5 程序的暂停2.6 字符串的比较 3. 结构化3.1 顺序结构3.2 分支结构3.3 循环结构 4. 真假性5. 分支语句&#xff08;选择结构&#xff09;5.1 if语句5.1.1 语法形式5.1.2 else…

Java网络通信UDP

目录 网络通信基础 UDP通信 服务器 1.想要使用UDP通信 要先打开DatagramSocket文件 端口号可以手动指定或系统随机分配 2.阻塞等待接收客户端数据&#xff1b;创建DatagramPacket接收客户端传来的数据 3.处理客户端传来的数据&#xff0c;并进行业务处理&#xff08;这里…

MySQL 教程 2.4

MySQL UNION 操作符 本教程为大家介绍 MySQL UNION 操作符的语法和实例。 描述 MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合&#xff0c;并去除重复的行。 UNION 操作符必须由两个或多个 SELECT 语句组成&#xff0c;每个 SELECT 语句的列数…

Python降维数据库之umap使用详解

概要 在数据科学和机器学习领域,数据通常是高维度的,而高维度数据不仅难以可视化,还会增加建模的复杂性。降维是一种处理高维数据的关键技术,而Python UMAP(Uniform Manifold Approximation and Projection)是一种强大的降维工具,它在保留数据结构的同时,将高维数据映…

【IDEA+通义灵码插件】实现属于你的大模型编程助手

目录 1.前言 2.下载安装 3.解释代码 4.生成单元测试 5.生成注释 6.智能补全 1.前言 大模型到底该以一种什么方式落地&#xff0c;从而嵌入我们的工作当中&#xff0c;助力我们工作效率的提升&#xff0c;其实最好的方式也许就是虚拟助手的方式&#xff0c;就像钢铁侠的&…

【OpenCV基础(三)】Ubuntu系统下EasyPR环境配置

环境配置 1、资源下载2、环境配置2.1、1、将EasyPR压缩包拷贝到Ubuntu 三种方法任选一种2.2、解压得到EasyPR文件夹(文件夹一层进入后EasyPR资源内容)2.3、终端命令修改权限**chmod -R 777 ./ EasyPR**2.4、查找EasyPR/include/easypr/config.h&#xff0c;使用gedit方式打开2.…