Java设计模式——职责链模式:解锁高效灵活的请求处理之道

嘿,各位 Java 编程大神和爱好者们!今天咱们要一同深入探索一种超厉害的设计模式——职责链模式。它就像一条神奇的“处理链”,能让请求在多个对象之间有条不紊地传递,直到找到最合适的“处理者”。准备好跟我一起揭开它神秘的面纱,看看如何用代码实现这种强大的模式,让我们的程序变得更加智能和灵活吧!💥

一、职责链模式:请求处理的“智能传送带”🎯

(一)模式定义与神奇特点

职责链模式可是对象行为模式家族里的“明星成员”哦!想象一下,有一群对象像链条上的环一样紧密相连,每个对象都知道下一个对象是谁(持有下家的引用)。当一个请求像小包裹一样在这条链上传递时,它会逐个经过这些对象。而发出请求的客户端呢,就像把包裹送到快递公司后就安心等待结果一样,完全不用操心到底是哪个对象最终会处理这个请求。这种模式最大的魅力在于它赋予了系统超级强大的灵活性。比如说,我们可以随时调整这条链的结构,添加、删除或者重新排列处理者,而客户端那边却感觉不到任何变化,就像魔法一样!🧙‍♂️

用一个超形象的比喻来理解,职责链模式就像是一场接力赛跑,每个选手(处理者)都有自己的能力范围(处理条件)。当接力棒(请求)传来时,如果这个选手有能力完成接下来的路程(处理请求),那就全力冲刺;如果觉得自己力不从心,就迅速把接力棒交给下一个选手,直到找到那个能冲过终点线(处理请求)的“大神”选手。

再举个生活中的例子,就拿击鼓传花来说吧。一群小伙伴围成一个圈(形成责任链),鼓声响起时开始传花(请求传递)。每个小伙伴就像是链上的一个处理者,当花传到自己手上时,如果鼓声停止(满足某种条件),那这个小伙伴就要表演节目(处理请求);如果鼓声还在响,就赶紧把花传给下一个小伙伴。这里的小伙伴们可以站成直线、围成环形或者组成树状结构的一部分,具体怎么站完全取决于大家想怎么玩这个游戏(业务逻辑和需求)。🎊

(二)模式结构大揭秘

  1. 抽象处理者(Handler):链的“基石”与“规则制定者”
    • 抽象处理者就像是整个职责链的“总设计师”,它定义了处理请求的统一接口,就像给所有处理者制定了一套必须遵守的“游戏规则”。在某些情况下,它还会规定怎么设置和获取下一个处理者(下家)的方法。一般来说,它会以抽象类或者接口的形式存在,为具体的处理者提供了一个清晰的行为框架和接口规范,确保所有处理者都能“按章办事”。就好比建筑蓝图,规定了房子该怎么盖,每个房间的布局和功能一样。🏠
  2. 具体处理者(ConcreteHandler):请求的“接收者”与“传递者”
    • 具体处理者可是链上的“实干家”,当请求送到它面前时,它有两种选择。一种是根据自己的能力和判断,决定是否亲自处理这个请求。如果它觉得自己能行,就会按照自己的方式处理请求,就像厨师根据订单(请求)烹饪美食(处理逻辑);另一种情况是,如果它觉得自己搞不定,或者根据业务规则应该让更厉害的人来处理,它就会毫不犹豫地把请求转交给下家。因为它知道下家是谁(持有下家引用),所以能轻松地把请求传递下去,让请求继续在链上“旅行”。就像快递员,如果发现包裹的目的地不在自己的配送范围内,就会转交给下一个区域的快递员。🚚

(三)代码实现:构建职责链

下面是一个用 Java 实现的职责链模式的简单示例代码,让我们一起来看看它是如何工作的。

// 抽象处理者(Handler)
abstract class Handler {// 持有下一个处理者的引用protected Handler successor;// 设置下一个处理者的方法public void setSuccessor(Handler successor) {this.successor = successor;}// 抽象的处理请求方法,具体处理逻辑由子类实现abstract public void handleRequest(int request);
}// 具体处理者 1(ConcreteHandler1)
class ConcreteHandler1 extends Handler {@Overridepublic void handleRequest(int request) {// 如果请求在 0 到 10 之间(这里只是一个简单的示例条件),则由当前处理者处理if (request >= 0 && request < 10) {System.out.println(this + " handled request " + request);} else if (successor!= null) {// 否则,将请求传递给下一个处理者(如果有下家的话)successor.handleRequest(request);}}
}// 具体处理者 2(ConcreteHandler2)
class ConcreteHandler2 extends Handler {@Overridepublic void handleRequest(int request) {if (request >= 10 && request < 20) {System.out.println(this + " handled request " + request);} else if (successor!= null) {successor.handleRequest(request);}}
}// 具体处理者 3(ConcreteHandler3)
class ConcreteHandler3 extends Handler {@Overridepublic void handleRequest(int request) {if (request >= 20 && request < 30) {System.out.println(this + " handled request " + request);} else if (successor!= null) {successor.handleRequest(request);}}
}// 客户端测试类
public class Client {public static void main(String[] args) {// 创建处理者对象Handler h1 = new ConcreteHandler1();Handler h2 = new ConcreteHandler2();Handler h3 = new ConcreteHandler3();// 设置处理者之间的链关系,形成 h1 -> h2 -> h3 的链h1.setSuccessor(h2);h2.setSuccessor(h3);// 生成一些请求并处理int[] requests = {2, 5, 14, 22, 18, 3, 27, 20};for (int request : requests) {h1.handleRequest(request);}}
}

Responsibility.jpg

(四)纯与不纯的职责链模式

  1. 纯职责链模式:规则严格的“处理链”
    • 在纯职责链模式的世界里,规则那是相当严格的。对于每一个具体的处理者来说,当收到请求时,它只能二选一:要么勇敢地承担起处理请求的全部责任,就像独自扛起一座大山;要么毫不犹豫地把责任推给下家,绝不拖泥带水。而且,在这条链上,每个请求就像一个被精心安排的小旅客,必定会被某个处理者收留并妥善处理,绝对不会出现被忽视、流落街头的情况。不过呢,这种模式在现实生活中的例子比较少,因为它的实现和应用场景相对来说有点“挑食”,要求比较高,不够灵活。就像一个只接受特定规格零件的精密仪器,稍微有点不匹配就无法工作。🔍
  2. 不纯职责链模式:适应变化的“万能链”
    • 不纯职责链模式就随和多了,它允许请求在传递过程中,即使经过了所有的处理者,也可能找不到一个愿意收留它的“家”。这种模式在实际开发中可是非常受欢迎的“大众明星”,因为它能更好地应对复杂多变的业务需求。比如说,在某些业务场景中,一个请求可能像一个挑剔的顾客,在经过一系列的服务者(处理者)后,还是没有找到满意的服务(没有合适的处理者)。这时候,系统可以根据预先设定的策略,比如记录下这个“挑剔顾客”的需求(记录日志),或者礼貌地告诉它“不好意思,我们无法满足您的需求”(返回错误信息)。就像一家餐厅,如果遇到顾客点了菜单上没有的菜品,服务员可以记录下来反馈给厨房(记录日志),或者向顾客解释并推荐其他菜品(返回错误信息)。🍽

(五)实际应用案例:采购审批系统中的职责链

让我们来看一个更贴近实际工作场景的例子——采购审批系统。

// 抽象审批者(Approver)
abstract class Approver {// 审批者姓名protected String name;// 持有下一个审批者的引用protected Approver successor;// 构造函数,初始化审批者姓名public Approver(String name) {this.name = name;}// 设置下一个审批者的方法public void setSuccessor(Approver successor) {this.successor = successor;}// 抽象的审批请求方法,具体审批逻辑由子类实现abstract public void processRequest(PurchaseRequest request);
}// 主管审批者(Director)
class Director extends Approver {public Director(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 10000.0) {System.out.println(this + " " + name + " approved request# " + request.getNumber());} else if (successor!= null) {successor.processRequest(request);}}
}// 副总裁审批者(VicePresident)
class VicePresident extends Approver {public VicePresident(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 25000.0) {System.out.println(this + " " + name + " approved request# " + request.getNumber());} else if (successor!= null) {successor.processRequest(request);}}
}// 总裁审批者(President)
class President extends Approver {public President(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest request) {if (request.getAmount() < 100000.0) {System.out.println(this + " " + name + " approved request# " + request.getNumber());} else {System.out.println("Request# " + request.getNumber() + " requires an executive meeting!");}}
}// 采购请求类(PurchaseRequest)
class PurchaseRequest {private double amount;private int number;public PurchaseRequest(double amount, int number) {this.amount = amount;this.number = number;}public double getAmount() {return amount;}public int getNumber() {return number;}
}

在这个采购审批系统中,我们定义了不同级别的审批者,从主管、副总裁到总裁,他们就像一条职责链上的各个环节。当一个采购请求(就像一个任务包裹)被提交后,它会从主管开始,沿着这条审批链依次传递。如果采购金额比较小,比如小于 10000 元,主管就可以直接批准(处理请求);如果金额超过了主管的审批权限,主管就会把请求交给副总裁。副总裁也会根据金额大小决定是否批准,如果金额超过了副总裁的权限,就继续传递给总裁。这样,不同金额的采购请求就能找到合适的审批者进行处理。而且,如果未来公司的审批流程发生了变化,比如增加了新的审批层级或者修改了审批金额的限制,我们只需要在相应的审批者类中进行修改,就像调整链条上的某个环节一样,不会对整个审批系统的结构造成太大的影响。这就是职责链模式在实际应用中的强大之处,它让系统变得更加灵活和易于维护。💼

二、总结与展望:职责链模式的无限潜力💡

通过对职责链模式的深入学习,我们就像获得了一把神奇的钥匙,可以打开高效灵活处理请求的大门。它不仅让我们的代码结构更加清晰,各个处理者之间的职责分明,还让系统能够轻松应对各种变化,无论是业务规则的调整还是处理流程的优化。

在未来的开发中,我们可以继续探索职责链模式的更多应用场景,比如在工作流系统、消息处理系统、异常处理机制等方面都可以发挥它的优势。同时,我们也可以结合其他设计模式,如工厂模式来创建处理者对象,或者结合装饰者模式来增强处理者的功能,让我们的程序更加健壮和强大。相信只要我们善于运用这些设计模式,就能打造出更加优秀、高效的软件系统,在编程的世界里创造更多的精彩!🚀

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

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

相关文章

Android 设备使用 Wireshark 工具进行网络抓包

背景 电脑和手机连接同一网络&#xff0c;想使用wireshark抓包工具抓取Android手机网络日志&#xff0c;有以下两种连接方法&#xff1a; Wi-Fi 网络抓包。USB 网络共享抓包。需要USB 数据线将手机连接到电脑&#xff0c;并在开发者模式中启用 USB 网络共享。 查看设备连接信…

redis大key和热key

redis中大key、热key 什么是大key大key可能产生的原因大key可能会造成什么影响如何检测大key如何优化删除大key时可能的问题删除大key的策略 热key热key可能导致的问题解决热key的方法 什么是大key 大key通常是指占用内存空间过大或包含大量元素的键值对。 数据量大&#xff…

SpringBoot源码-spring boot启动入口ruan方法主线分析(二)

12.刷新前操作 // 刷新前操作prepareContext(context, environment, listeners, applicationArguments, printedBanner);进入prepareContext private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRun…

使用 VLC 在本地搭建流媒体服务器 (详细版)

提示&#xff1a;详细流程 避坑指南 Hi~&#xff01;欢迎来到碧波空间&#xff0c;平时喜欢用博客记录学习的点滴&#xff0c;欢迎大家前来指正&#xff0c;欢迎欢迎~~ ✨✨ 主页&#xff1a;碧波 &#x1f4da; &#x1f4da; 专栏&#xff1a;音视频 目录 借助VLC media pl…

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】

【单片机毕业设计12-基于stm32c8t6的智能称重系统设计】 前言一、功能介绍二、硬件部分三、软件部分总结 前言 &#x1f525;这里是小殷学长&#xff0c;单片机毕业设计篇12-基于stm32c8t6的智能称重系统设计 &#x1f9ff;创作不易&#xff0c;拒绝白嫖可私 一、功能介绍 ----…

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…

输入json 达到预览效果

下载 npm i vue-json-pretty2.4.0 <template><div class"newBranchesDialog"><t-base-dialogv-if"addDialogShow"title"Json数据配置"closeDialog"closeDialog":dialogVisible"addDialogShow":center"…

ML 系列:第 32节 — 机器学习中的统计简介

文章目录 一、说明二、统计概述三、描述性统计与推断性统计3.1 描述统计学3.2 推论统计 四、描述性统计中的均值、中位数和众数 一、说明 机器学习中的统计 随着我们深入研究机器学习领域&#xff0c;了解统计学在该领域的作用至关重要。统计学是机器学习的支柱&#xff0c;它…

大数据新视界 -- Hive 数据分区:精细化管理的艺术与实践(上)(7/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

VTK的基本概念(一)

文章目录 三维场景的基本要素1.灯光2.相机3.颜色4.纹理映射 三维场景的基本要素 1.灯光 在三维渲染场景中&#xff0c;可以有多个灯光的存在&#xff0c;灯光和相机是三维渲染场景的必备要素&#xff0c;如果没有指定的话&#xff0c;vtkRenderer会自动创建默认的灯光和相机。…

简单好用的折线图绘制!

折线图的概念及作用&#xff1a; 折线图&#xff08;Line Chart&#xff09;是一种常见的图表类型&#xff0c;用于展示数据的变化趋势或时间序列数据。它通过一系列的数据点&#xff08;通常表示为坐标系中的点&#xff09;与这些点之间的线段相连&#xff0c;直观地展示变量…

简单线性DP

数字三角形--简单线性DP 题目链接&#xff1a;数字三角形 解题代码&#xff1a; import java.io.BufferedReader; import java.io.InputStreamReader;public class Main {static int N510;static int INF (int) -1e9;static String[] q;static int[][]fnew int[N][N];static …

【数据结构】双向链表、单向循环链表、双向循环链表、栈、链栈

目录 一、双向链表 定义类和封装函数以及测试样例如下&#xff1a; 注意事项&#xff1a; 二、循环链表 单循环列表的类和函数封装如下&#xff1a; 注意事项&#xff1a; 三、双向循环链表 结点类和双循环链表的定义部分 函数封装之判空和尾插 双循环链表遍历 双循…

win10中使用ffmpeg的filter滤镜

1 给视频加文字水印 1.1 添加播放时间 ffmpeg -i input.mp4 -vf "drawtextfontfileC\\:/Windows/fonts/consola.ttf:fontsize30:fontcolorwhite:timecode00\:00\:00\:00:rate25:textTCR\::boxcolor0x000000AA:box1:x20:y20" -y output.mp4 在视频的x20:y20位置添加t…

CentOS7执行yum命令报错,已加载插件:fastestmirrorLoading mirror speeds from cached hostfile

一、出现一下异常问题&#xff0c;表示域名没有配置或配置错误 问题一&#xff1a; 0curl: (6) Could not resolve host: mirrors.aliyun.com; 未知的错误 问题二&#xff1a;虚拟机使用ping主机&#xff0c;提示network unreachable 2.原因分析 出现这个问题是因为yum在安装…

基于WEB的房屋出租管理系统设计

摘 要 在当今社会的蓬勃发展的现状下&#xff0c;网络与我们的生活息息相关。工作、生活、休闲我们都利用着网络带给我们 的便捷&#xff0c;网络的发展提供了很多工作机会&#xff0c;众多的人们在不同的城市寻找着合适的工作机会&#xff0c;在此的第一步就是寻 找一个合适自…

nginx安装和负载均衡

1. nginx安装 &#xff08;1&#xff09;安装依赖项&#xff1a; yum -y install gcc gcc-c make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel&#xff08;2&#xff09;下载Nginx源代码&#xff1a; http://nginx.org/en/download.html https://nginx.o…

Sharding 分片

Sharding 分片 分片机制的概念 Sharding is a method for distributing data across multiple machines. MongoDB uses sharding to support deployments with very large data sets and high throughput operations. 分片&#xff08;Shard&#xff09; 每个分片&#xff08…

使用API管理Dynadot域名,在账户中添加域名服务器(Name Server)

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

http账号密码认证Http Basic Auth

1.1 Http Basic Auth 这是一种最古老的安全认证方式&#xff0c;这种方式就是简单的访问API的时候&#xff0c;带上访问的username和password&#xff0c;由于信息会暴露出去&#xff0c;所以现在也越来越少用了&#xff0c;现在都用更加安全保密的认证方式&#xff0c;可能某…