当前位置: 首页 > news >正文

Java 责任链模式详解

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,使得多个对象都有机会处理这个请求。在责任链模式中,有一个请求处理链条,每个处理请求的对象都是一个节点,当请求进入这个链条时,链条上的节点逐一判断是否能够处理该请求,如果可以,则处理;否则,将请求传递给下一个节点,直到请求被处理为止。

责任链模式可以有效地避免请求发送者与接收者之间的耦合,将请求处理对象按照顺序串联起来形成一个链条,每个节点都可以根据自己的职责进行处理,可以动态地增加、删除或修改节点。责任链模式常用于处理请求的场景,例如登录验证、权限校验、日志记录、异常处理等。

本文将详细介绍 Java 中的责任链模式,包括其概念、结构、实现方式以及应用案例等,帮助读者更好地理解和应用责任链模式。

一、概念

责任链模式定义了一个请求处理对象的链条,每个对象都可以处理请求或者将请求转发给下一个对象,直到有一个对象处理请求为止。在责任链模式中,请求发送者不需要知道链条中具体的处理对象,只需要将请求发送给链头即可,具体的处理过程和实现细节由链条中的对象来决定。责任链模式可以有效地解耦请求发送者和接收者,分离职责,提高系统的灵活性和可维护性。

责任链模式包含以下几个角色:

  • Handler(处理者):定义了处理请求的接口,通常包含一个抽象方法或者一个处理请求的抽象类。每个处理者都知道自己的后继者(下一个处理者),如果自己不能处理该请求,则将其转发给后继者。
  • ConcreteHandler(具体处理者):实现了 Handler 接口,并对请求进行实际处理。每个具体处理者都能够处理一些特定的请求类型,如果自己不能处理该请求,则将其转发给后继者。
  • Client(客户端):创建链条的起点,向链条头部的处理者发送请求。

二、结构

责任链模式的结构比较简单,主要包括以下几个部分:

在这里插入图片描述
其中,Handler 是一个抽象类或接口,定义了处理请求的方法 handleRequest() 和设置后继节点的方法 setSuccessor()。ConcreteHandler 类继承了 Handler 并实现了 handleRequest() 方法,在方法中判断是否能够处理该请求,如果能够处理则进行处理;否则将请求转发给下一个处理者。Client 类创建责任链的头部(即第一个 ConcreteHandler 对象),并向它发送请求。

三、实现方式

  1. 单向链表实现

单向链表是最常见的责任链模式实现方式,具有以下特点:

  • 链表中节点的处理顺序与其添加顺序相同。
  • 可以动态添加、删除或修改节点。

单向链表实现的核心代码如下:

public abstract class Handler {private Handler successor;  // 后继节点public void setSuccessor(Handler successor) {this.successor = successor;}// 处理请求的抽象方法public abstract void handleRequest(Request request);protected void next(Request request) {if (successor != null) {  // 如果有后继节点,则转发请求successor.handleRequest(request);}}
}public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(Request request) {if (canHandle(request)) {  // 判断是否能够处理该请求// 处理请求} else {next(request);  // 转发请求给下一个处理者}}private boolean canHandle(Request request) {// 判断是否能够处理该请求的逻辑}
}public class Client {public static void main(String[] args) {Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();handlerA.setSuccessor(handlerB);  // 设置后继节点Request request = new Request();handlerA.handleRequest(request);  // 发送请求到链头}
}
  1. 数组或队列实现

除了单向链表,还可以使用数组或队列等数据结构来实现责任链模式,主要思想是将处理者放在一个数组或队列中按序存储。这种实现方式比较简单,但不够灵活,并且不支持动态添加、删除或修改节点。

数组或队列实现的核心代码如下:

public abstract class Handler {// ...// 处理请求的抽象方法public abstract void handleRequest(Request request);protected void next(Request request, Handler[] handlers, int index) {if (index < handlers.length) {  // 如果有后继节点,则转发请求handlers[index].handleRequest(request);}}
}public class Client {public static void main(String[] args) {Handler[] handlers = new Handler[] {new ConcreteHandlerA(), new ConcreteHandlerB()};Request request = new Request();handlers[0].handleRequest(request, handlers, 1);  // 发送请求到链头}
}

四、应用案例

责任链模式在Java中有许多应用场景,例如:

  1. 过滤器(Filter):在Servlet中,过滤器就是使用责任链模式实现的。每个过滤器都可以决定是否处理请求,或者将其转发给下一个过滤器进行处理。

  2. 拦截器(Interceptor):在Spring框架中,拦截器就是使用责任链模式实现的。拦截器可以对请求进行预处理或后处理,也可以将请求转发给下一个拦截器进行处理。

  3. 异常处理(Exception Handling):在Java中,可以使用责任链模式来处理异常。首先,程序先尝试使用自定义的异常处理器来处理异常,如果该处理器无法处理异常,则将其转发给下一个处理器进行处理。

  4. 日志记录(Logger):在Java中,可以使用责任链模式来记录日志。每个日志记录器都可以决定是否需要记录该日志,或者将其转发给下一个日志记录器进行记录。

五、总结

责任链模式是一种常见的设计模式,在Java中有多种实现方式。通过责任链模式,可以将请求发送者和接收者解耦,提高系统的灵活性和可维护性。在实际应用中,可以将责任链模式应用于过滤器、拦截器、异常处理、日志记录等场景,从而实现统一的处理逻辑。

相关文章:

Java 责任链模式详解

责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于将请求的发送者和接收者解耦&#xff0c;使得多个对象都有机会处理这个请求。在责任链模式中&#xff0c;有一个请求处理链条&#xff0c;每个处理请求的对象都是一个…...

使用MASA全家桶从零开始搭建IoT平台(三)管理设备的连接状态

文章目录 前言分析方案1:遗嘱消息演示遗嘱消息的使用实施流程 方案2:使用WebHook开启WebHook演示Webhook编写代码 前言 获取一个设备的在线和离线状态&#xff0c;是一个很关键的功能。我们对设备下发的控制指令&#xff0c;设备处于在线状态才能及时给我们反馈。这里的在线和…...

我的新书上架了!

talk is cheap&#xff0c;show you my book&#xff01; 新书《从0开始学ARM》终于在各大平台上架了&#xff01;&#xff01; 一、关于本书 1. 本书主要内容 ARM体系架构是目前市面上的主流处理器体系架构&#xff0c;在手机芯片和嵌入式芯片领域&#xff0c;ARM体系架构…...

语言与专业的奇迹:如何利用ChatGPT优化跨国贸易

贸易公司&#xff0c;在进行跨国贸易时&#xff0c;往往需要面对不同国家的甲方或者乙方&#xff0c;在与之沟通的过程中&#xff0c;语言和专业是必须要过的一关&#xff0c;顺畅的交流&#xff0c;往往会带来更好的收益。 今天以“茶”为例&#xff0c;给大家介绍一“知否AI…...

云服务器安装宝塔Linux面板命令脚本大全

阿里云服务器安装宝塔Linux面板&#xff0c;操作系统不同安装命令脚本也不同&#xff0c;支持CentOS、Alibaba Cloud Linux、Ubuntu/Deepin等Linux系统&#xff0c;阿里云服务器网分享阿里云服务器安装宝塔Linux面板命令脚本大全&#xff1a; 云服务器安装宝塔Linux面板命令 …...

zed2i相机中imu内参的标定及外参标定

zed2i中imu内参的标定 参考&#xff1a; https://blog.csdn.net/weixin_42681311/article/details/126109617 https://blog.csdn.net/weixin_43135184/article/details/123444090 值得注意&#xff0c;imu内参的标定其实不是那么重要&#xff0c;大致上给一个值应该影响不大…...

Java中的JUnit是什么?如何使用JUnit进行单元测试

JUnit是Java中最流行的单元测试框架之一。它可以帮助开发人员在代码编写过程中检测出错误和异常&#xff0c;从而提高代码的质量和可靠性。 什么是JUnit&#xff1f; JUnit是一个由Kent Beck和Erich Gamma创建的开源Java单元测试框架&#xff0c;它已经成为Java开发中最常用的…...

【seata的部署和集成】

seata的部署和集成 seata的部署和集成一、部署Seata的tc-server1.下载2.解压3.修改配置4.在nacos添加配置5.创建数据库表6.启动TC服务 二、微服务集成seata1.引入依赖2.修改配置文件 三、TC服务的高可用和异地容灾1.模拟异地容灾的TC集群2.将事务组映射配置到nacos3.微服务读取…...

uniapp学习日记之request自定义请求头

uniapp学习日记之request自定义请求头 在学习uniapp的过程中&#xff0c;由于笔者是从Vue项目转来学习uniapp&#xff0c;在使用uni.request时&#xff0c;发现在浏览器调试时&#xff0c;无法在请求头header中添加token字段&#xff0c;愤而弃之&#xff0c;便开始使用axios组…...

【Rust】速度入门---打印个螃蟹先

参考: 菜鸟教程 1 输出到命令行 这不得打印个螃蟹 // 代码来自官方入门教程 // ferris_say需要另外安装 use ferris_says::say; use std::io::{stdout, BufWriter};fn main() {let stdout: std::io::Stdout stdout();let msg: String String::from("Hello fellow Rusta…...

《Linux 内核设计与实现》12. 内存管理

文章目录 页区获得页获得填充为 0 的页释放页 kmalloc()gfp_mask 标志kfree()vmalloc() slab 层slab 层的设计slab 分配器的接口 在栈上的静态分配单页内核栈 高端内存的映射永久映射临时映射 每个 CPU 的分配新的每个 CPU 接口 页 struct page 结构表示系统中的物理页&#x…...

公司新来个卷王,让人崩溃...

最近内卷严重&#xff0c;各种跳槽裁员&#xff0c;相信很多小伙伴也在准备今年的面试计划。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必要的&#xff0c;它几乎涵盖了所有的软件测试技术栈&#xff0c;非常珍贵&#x…...

Docker 安全及日志管理

Docker 安全及日志管理 Docker 容器与虚拟机的区别隔离与共享性能与损耗 Docker 存在的安全问题Docker 自身漏洞Docker 源码问题Docker 架构缺陷与安全机制Docker 安全基线标准 容器相关的常用安全配置方法容器最小化Docker 远程 API 访问控制重启 Docker在宿主机的 firewalld …...

大厂面试必备 - MAC 地址 和 IP 地址分别有什么作用?

数据链路层 1、MAC 地址 和 IP 地址分别有什么作用&#xff1f; MAC 地址是数据链路层和物理层使用的地址&#xff0c;是写在网卡上的物理地址。MAC 地址用来定义网络设备的位置。IP 地址是网络层和以上各层使用的地址&#xff0c;是一种逻辑地址。IP 地址用来区别网络上的计…...

【sqlite】联查Join更新

系列文章 C#底层库–MySQLBuilder脚本构建类&#xff08;select、insert、update、in、带条件的SQL自动生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库操作辅助类&#xff08;推荐阅读&#xff0…...

asp.net+C#德育课程分数统计管理系统

本中小学德育管理系统主要学校内部提供服务&#xff0c;系统分为管理员&#xff0c;教师和学生3个大模块。 本研究课题重点主要包括了下面几大模块&#xff1a;用户登录&#xff0c;管理员信息管理学生信息管理&#xff0c;教师信息管理&#xff0c;班级成绩管理&#xff0c;学…...

Figma中文网?比Figma更懂你的设计网站!

一个比 Figma 更懂你的设计网站的 Figma 中文网 —— 即时设计是一个非常有用的设计资源平台&#xff0c;它提供了大量的免费设计素材&#xff0c;包括来自各大厂商的 UI 组件库、精美的模板、插画设计和矢量图标素材等等。设计师可以从中学习到大师的设计技巧和规范&#xff0…...

Nacos-01-Nacos基本介绍

背景 ​ 服务发现是⼀个古老的话题&#xff0c;当应用开始脱离单机运行和访问时&#xff0c;服务发现就诞生了。目前的网络架构是每个主机都有⼀个独立的 IP 地址&#xff0c;那么服务发现基本上都是通过某种方式获取到服务所部署的 IP 地址。DNS 协议是最早将⼀个网络名称翻译…...

SpringBoot集成Dubbo启用gRPC协议

文章目录 前言项目结构代码示例父工程api moduleservice module 注意事项区别 本文记录下SpringBoot集成Dubbo启用gRPC协议&#xff0c;以及与原生 gRPC 在代码编写过程中的区别。 下面还有投票&#xff0c;帮忙投个票&#x1f44d; 前言 Dubbo 在 2.7.5 版本开始支持原生 gRP…...

Kali HTTrack演示-渗透测试察打一体(1)

HTTrack是一个免费并易于使用的线下浏览器工具,全称是HTTrack Website Copier for Windows,它能够让你从互联网上下载指定的网站进行线下浏览(离线浏览),也可以用来收集信息(甚至有网站使用隐藏的密码文件),一些仿真度极高的伪网站(为了骗取用户密码),也是使用类似工具做…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...