23种设计模式-责任链(Chain of Responsibility)设计模式

news2025/4/3 2:28:54

责任链设计模式

  • 🚩什么是责任链设计模式?
  • 🚩责任链设计模式的特点
  • 🚩责任链设计模式的结构
  • 🚩责任链设计模式的优缺点
  • 🚩责任链设计模式的Java实现
  • 🚩代码总结
  • 🚩总结

🚩什么是责任链设计模式?

责任链设计模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

使用场景

  • 当需要 多个对象可以处理同一个请求,但具体由哪个对象处理在运行时动态决定时

  • 当需要 在不明确指定接收者的情况下向多个对象中的一个提交请求

  • 当需要 动态指定一组对象处理请求 时(如审批流程、异常处理等)

🚩责任链设计模式的特点

  • 解耦请求发送者和接收者:发送者无需知道具体由哪个对象处理请求

  • 动态组合处理链:可以动态地添加或修改处理请求的责任链

  • 灵活性高:可以灵活地分配责任或改变处理顺序

  • 多种处理方式:请求可以被链中的某个对象处理,也可以不被任何对象处理

🚩责任链设计模式的结构

责任链模式主要包含以下部分:

  • Handler(抽象处理者):定义处理请求的接口,通常包含设置下一个处理者的方法和处理请求的方法

  • ConcreteHandler(具体处理者):实现处理请求的具体逻辑,如果不能处理则转发给下一个处理者

  • Client(客户端):创建处理链并向链头的处理者提交请求

图例:

在这里插入图片描述

🚩责任链设计模式的优缺点

✅ 优点

  • 降低耦合度:请求发送者只需知道链中的第一个处理者

  • 增强灵活性:可以动态地增加或修改处理链

  • 简化对象间的连接:每个处理者只需保持一个指向其后继者的引用

  • 分配责任更灵活:可以自由分配责任或改变责任顺序

❌ 缺点

  • 请求可能不被处理:如果没有处理者能够处理请求,它可能会到达链的末端并被丢弃

  • 性能问题:较长的责任链可能会影响性能,特别是在链的末端才找到处理者时

  • 调试困难:请求的传递过程可能比较复杂,不容易调试

🚩责任链设计模式的Java实现

代码地址:GitHub

  • 创建 抽象主题 Handler接口
/**
 * @author hanson.huang
 * @version V1.0
 * @ClassName Handler
 * @Description 抽象类定义了处理请求的接口和设置下一个处理者的方法
 * @date 2025/3/25 15:45
 **/
public abstract class Handler {
    protected Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public abstract void HandlerRequest(int request);
}
  • 创建三个具体的处理者,实现自己的逻辑

    • FuDaoYuan处理者
    /**
     * @author hanson.huang
     * @version V1.0
     * @ClassName FuDaoYuan
     * @Description FuDaoYuan处理者
     * @date 2025/3/25 15:47
     **/
    public class FuDaoYuan extends Handler { // <= 7 审批
    
        @Override
        public void HandlerRequest(int request) {
            if (request <= 7) {
                System.out.println("辅导员审批通过");
            } else {
                if (next != null) {
                    next.HandlerRequest(request);
                } else {
                    System.out.println("无法审批");
                }
            }
        }
    }
    
    • YuanZhang处理者
    /**
     * @author hanson.huang
     * @version V1.0
     * @ClassName YuanZhang
     * @Description YuanZhang处理者
     * @date 2025/3/25 15:51
     **/
    public class YuanZhang extends Handler {
    
        @Override
        public void HandlerRequest(int request) {
            if (request <= 15) {
                System.out.println("院长审批通过");
            } else {
                if (next != null) {
                    next.HandlerRequest(request);
                } else {
                    System.out.println("无法审批");
                }
            }
        }
    }
    
    • XiaoZhang处理者
    /**
     * @author hanson.huang
     * @version V1.0
     * @ClassName XiaoZhang
     * @Description XiaoZhang处理者
     * @date 2025/3/25 15:52
     **/
    public class XiaoZhang extends Handler {
    
        @Override
        public void HandlerRequest(int request) {
            if (request <= 30) {
                System.out.println("校长审批通过");
            } else {
                if (next != null) {
                    next.HandlerRequest(request);
                } else {
                    System.out.println("无法审批");
                }
            }
        }
    }
    
  • 测试责任链模式

/**
 * @author hanson.huang
 * @version V1.0
 * @ClassName ChainOfResponsibilityPattern
 * @Description 测试责任链模式
 * @date 2025/3/25 15:54
 **/
public class ChainOfResponsibilityPattern {
    public static void main(String[] args) {
        FuDaoYuan fuDaoYuan = new FuDaoYuan();
        YuanZhang yuanZhang = new YuanZhang();
        XiaoZhang xiaoZhang = new XiaoZhang();

        fuDaoYuan.setNext(yuanZhang);
        yuanZhang.setNext(xiaoZhang);

        fuDaoYuan.HandlerRequest(31);
        fuDaoYuan.HandlerRequest(25);
    }
}

📌 运行结果

传入31时,显示无法审批
传入25时,校长审批通过

在这里插入图片描述

🚩代码总结

  • Handler 抽象类定义了处理请求的接口和设置下一个处理者的方法

  • FuDaoYuanYuanZhangXiaoZhang 是具体的处理者,实现了自己的处理逻辑

  • ChainOfResponsibilityPattern 类构建了处理链并触发请求

  • 每个处理者如果不能处理当前请求,会将请求传递给链中的下一个处理者

🚩总结

  • 责任链设计模式 通过构建一条处理链来解耦请求发送者和接收者

  • 核心是 让多个对象都有机会处理请求,避免请求发送者与接收者之间的耦合

  • 适用于 多级审批、异常处理、事件传递 等场景

✅ Java源码中的应用场景:

  1. Java Servlet中的FilterChain

    • javax.servlet.FilterChain

    • 多个Filter组成责任链处理HTTP请求

  2. Java异常处理机制:

    • 异常在调用栈中向上传播的过程就是责任链模式的应用
  3. Spring Security的过滤器链:

    • 多个安全过滤器组成责任链处理安全相关逻辑
  4. Netty的ChannelPipeline:

    • 处理器链处理网络事件
  5. AWT/Swing事件处理:

    • 事件在组件层次结构中的传播
  6. Log4j/Logback日志框架:

    • 日志级别过滤和处理的链式结构

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

在这里插入图片描述

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

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

相关文章

Linux使用集群服务器查看已安装conda环境,且环境名无显示、系统环境混乱等问题

一、问题 在使用集群服务器前可以查看导入&#xff0c;module load不需要安装。我都是自己重新下载Anaconda3-2024.10-1-Linux-x86_64.sh&#xff0c;然后安装&#xff0c;导致混乱。下面是情况 1.创建的环境名跑到目录下了 2.多个base,且有个base无显示 二、解决办法 1.删…

python蓝桥杯刷题的重难点知识笔记

1、datetime模块 datetime.date&#xff1a;代表日期&#xff0c;包含年、月、日信息。datetime.time&#xff1a;代表时间&#xff0c;包含时、分、秒、微秒信息。datetime.datetime&#xff1a;结合了日期和时间&#xff0c;包含年、月、日、时、分、秒、微秒信息。datetime.…

Android平台毫秒级低延迟HTTP-FLV直播播放器技术探究与实现

一、前言 在移动互联网蓬勃发展的今天&#xff0c;视频播放功能已成为众多Android应用的核心特性之一。面对多样化的视频格式和传输协议&#xff0c;开发一款高效、稳定的视频播放器是许多开发者追求的目标。FLV&#xff08;Flash Video&#xff09;格式&#xff0c;尽管随着H…

极光优化PLO-Transformer-LSTM多变量时序

极光优化算法(PLO)于2024年8月发表于SCI期刊《Neurocomputing》&#xff0c;利用算法极光优化算法PLO优化Transformer-LSTM模型&#xff0c;同时提供与未优化模型的对比&#xff0c;包含柱状图、两张雷达图、二维散点图等等。 &#xff08;一&#xff09;LSTM模型LSTM是一种在时…

基于javaweb的SpringBoot智能无人仓库管理设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

python处理音频相关的库

1 音频信号采集与播放 pyaudio import sys import pyaudio import wave import timeCHUNK 1024 FORMAT pyaudio.paInt16 CHANNELS 1#仅支持单声道 RATE 16000 RECORD_SECONDS 3#更改录音时长#录音函数&#xff0c;生成wav文件 def record(file_name):try:os.close(file_…

网络爬虫-2:基础与理论

一.同步加载与异步加载 1.1同步加载定义: 页面所有内容一起加载出来,当某一个数据加载有问题,整个页面就不会加载出来(如HiFiNi音乐网站),所以又叫阻塞模式 1.2爬取步骤: 看netword->document 2.1异步加载定义: 数据是分开加载的,当某一份数据有异常时,不影响其他数据…

[项目]基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050配置与读取

基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050 一.芯片介绍二.配置I2C三.编写驱动四.读取任务的测试五.MPU6050六轴数据的校准 一.芯片介绍 芯片应该放置在PCB中间&#xff0c;X Y轴原点&#xff0c;敏感度131表示范围越小越灵敏。理想状态放置在地面上X&#xff0c;Y&#xf…

后端学习day1-Spring(八股)--还剩9个没看

一、Spring 1.请你说说Spring的核心是什么 参考答案 Spring框架包含众多模块&#xff0c;如Core、Testing、Data Access、Web Servlet等&#xff0c;其中Core是整个Spring框架的核心模块。Core模块提供了IoC容器、AOP功能、数据绑定、类型转换等一系列的基础功能&#xff0c;…

【赵渝强老师】在Docker中运行达梦数据库

Docker是一个客户端服务器&#xff08;Client-Server&#xff09;架构。Docker客户端和Docker守护进程交流&#xff0c;而Docker的守护进程是运作Docker的核心&#xff0c;起着非常重要的作用&#xff08;如构建、运行和分发Docker容器等&#xff09;。达梦官方提供了DM 8在Doc…

Python电影市场特征:AR模型时间序列趋势预测、热图可视化评分影响分析IMDb数据|附数据代码

原文链接&#xff1a;https://tecdat.cn/?p41214 分析师&#xff1a;Zhiheng Lin 在数字时代&#xff0c;电影产业的数据分析已成为洞察市场趋势与用户偏好的重要工具。本专题合集聚焦印度电影市场&#xff0c;通过IMDb数据集&#xff08;IMDb Movies Dataset&#xff09;的深…

扭蛋机小程序开发,潮玩娱乐消费风口下的机遇

随着Z世代消费能力的提升和盲盒经济的火爆&#xff0c;扭蛋文化正迎来爆发式增长。 扭蛋机作为一种充满惊喜感的消费模式&#xff0c;正从线下走向线上&#xff0c;并借助移动互联网实现了数字化转型。线上扭蛋机小程序不仅延续了传统扭蛋的趣味性&#xff0c;还通过数字化手段…

各类神经网络学习:(五)LSTM 长短期记忆(上集),结构详解

上一篇下一篇RNN&#xff08;下集&#xff09;待编写 LSTM&#xff08;长短期记忆&#xff09; 参考知乎文章《人人都能看懂的LSTM介绍及反向传播算法推导&#xff08;非常详细&#xff09; - 知乎》&#xff0c;部分图片也进行了引用。 参考视频教程《3.结合例子理解LSTM_哔哩…

计算机网络-2 物理层

【考纲内容】 &#xff08;一&#xff09;通信基础 信道、信号、带宽、码元、波特、速率、信源与信宿等基本概念&#xff1b; 奈奎斯特定理与香农定理&#xff1b;编码与调制&#xff1b; 电路交换、报文交换与分组交换&#xff1b;数据报与虚电路① 视频讲解 &#xff08;二…

Redis集群哨兵相关面试题

目录 1.Redis 主从复制的实现原理是什么? 详解 补充增量同步 replication buffer repl backlog buffer 2.Redis 主从复制的常见拓扑结构有哪些? 3.Redis 复制延迟的常见原因有哪些? 4.Redis 的哨兵机制是什么? 主观下线和客观下线 哨兵leader如何选出来的&#x…

Shopify Checkout UI Extensions

结账界面的UI扩展允许应用开发者构建自定义功能&#xff0c;商家可以在结账流程的定义点安装&#xff0c;包括产品信息、运输、支付、订单摘要和Shop Pay。 Shopify官方在去年2024年使用结账扩展取代了checkout.liquid&#xff0c;并将于2025年8月28日彻底停用checkout.liquid…

MOSN(Modular Open Smart Network)-04-TLS 安全链路

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFAStack-00-sofa 技术栈概览 MOSN&#xff08;Modular O…

Softmax 回归 + 损失函数 + 图片分类数据集

Softmax 回归 softmax 回归是机器学习另外一个非常经典且重要的模型&#xff0c;是一个分类问题。 下面先解释一下分类和回归的区别&#xff1a; 简单来说&#xff0c;分类问题从回归的单输出变成了多输出&#xff0c;输出的个数等于类别的个数。 实际上&#xff0c;对于分…

【C++】内存模型分析

在 C 语言中&#xff0c;程序运行时的内存通常被划分为以下几个区域&#xff1a; 代码区&#xff08;Text Segment&#xff09;常量区&#xff08;Constant Segment&#xff09;全局/静态区&#xff08;Data Segment&#xff0c;包含静态数据段和 BSS 段&#xff09;堆区&…