设计模式教程:责任链模式(Chain of Responsibility Pattern)

news2025/2/22 3:49:21

责任链模式(Chain of Responsibility Pattern)是一种常用的设计模式,它属于行为型模式,主要解决的是多个对象处理一个请求时,如何解耦请求的发送者和接收者,以及如何将请求的处理职责分配给不同的对象。

1. 责任链模式的定义:

责任链模式使得多个对象有机会处理请求,而不是由一个对象来处理请求。每个处理者都有一个指向下一个处理者的指针,当一个请求到达某个处理者时,它会决定自己是否能够处理该请求,如果能够处理就处理,否则将请求传递给下一个处理者。

2. 责任链模式的结构:

  • Handler(处理者):这是一个抽象类或接口,定义了处理请求的方法,通常是一个抽象方法 handleRequest(),并且通常会有一个指向下一个处理者的引用(即链条中的下一个对象)。

  • ConcreteHandler(具体处理者):每个具体的处理者类都实现了处理请求的逻辑。如果当前处理者不能处理该请求,它会将请求传递给链中的下一个处理者。具体处理者通常会根据某些条件判断是否能够处理请求。

  • Client(客户端):客户端负责将请求发送到链中的第一个处理者。客户端不关心请求如何被处理,只是把请求交给责任链的第一个处理者。

3. 责任链模式的流程:

  1. 客户端发送请求:客户端把请求交给链中的第一个处理者。
  2. 处理者判断是否能处理请求:每个处理者都可以根据自己的能力判断自己是否能处理这个请求。如果处理者能处理,则处理请求;否则,将请求传递给链中的下一个处理者。
  3. 继续传递请求:如果没有处理者能够处理请求,那么请求就会被完全传递出去,或者返回错误。

4. 责任链模式的优点:

  • 解耦请求的发送者和接收者:客户端不需要知道具体哪个处理者会处理请求,只是将请求交给责任链的第一个处理者,后续的责任链内部如何处理不需要关心。
  • 灵活性高:可以动态添加处理者。通过修改链中的处理者顺序或者添加新的处理者,可以很方便地改变处理流程。
  • 责任的分配更加清晰:每个处理者只需要关心自己能处理的任务,而不必了解整个请求的处理过程。

5. 责任链模式的缺点:

  • 性能问题:如果责任链过长,请求可能需要在链中传递很久,这会影响性能。
  • 责任链复杂:当责任链中有很多处理者时,维护责任链的代码可能变得复杂,尤其是当责任链变化频繁时。
  • 请求丢失问题:如果没有任何处理者处理请求,可能会导致请求丢失或者处理失败。

6. 责任链模式的示例:

6.1 简单的责任链实现

假设我们有三个不同的处理者,需要对请求进行处理,处理规则如下:

6.3 责任链模式的优化:

  • 请求的数字小于 10 由 ConcreteHandler1 处理。
  • 请求的数字介于 10 和 20 之间由 ConcreteHandler2 处理。
  • 请求的数字大于 20 由 ConcreteHandler3 处理。
    // Handler 抽象类
    abstract class Handler {
        protected Handler nextHandler; // 下一个处理者
    
        public void setNextHandler(Handler nextHandler) {
            this.nextHandler = nextHandler;
        }
    
        public abstract void handleRequest(int request);
    }
    
    // ConcreteHandler1
    class ConcreteHandler1 extends Handler {
        @Override
        public void handleRequest(int request) {
            if (request < 10) {
                System.out.println("ConcreteHandler1 handles request " + request);
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    // ConcreteHandler2
    class ConcreteHandler2 extends Handler {
        @Override
        public void handleRequest(int request) {
            if (request >= 10 && request < 20) {
                System.out.println("ConcreteHandler2 handles request " + request);
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    // ConcreteHandler3
    class ConcreteHandler3 extends Handler {
        @Override
        public void handleRequest(int request) {
            if (request >= 20) {
                System.out.println("ConcreteHandler3 handles request " + request);
            } else if (nextHandler != null) {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    // Client
    public class Client {
        public static void main(String[] args) {
            Handler handler1 = new ConcreteHandler1();
            Handler handler2 = new ConcreteHandler2();
            Handler handler3 = new ConcreteHandler3();
    
            // 设置责任链
            handler1.setNextHandler(handler2);
            handler2.setNextHandler(handler3);
    
            // 处理请求
            int[] requests = {5, 15, 25, 30};
    
            for (int request : requests) {
                handler1.handleRequest(request);
            }
        }
    }
    

    输出:

    ConcreteHandler1 handles request 5
    ConcreteHandler2 handles request 15
    ConcreteHandler3 handles request 25
    ConcreteHandler3 handles request 30
    
    6.2 责任链模式的应用场景
  • 日志处理:不同级别的日志(如调试、信息、警告、错误)可以通过责任链来处理,不同级别的日志传递给不同的处理者。
  • 用户请求处理:比如在电商系统中,用户的请求(如订单支付、退货申请等)可以通过责任链传递,处理者可以根据请求类型、用户权限等进行不同的处理。
  • 权限校验:多个权限校验规则可以通过责任链模式处理,用户请求可以依次通过不同的校验器。
  • 添加缓存机制:如果请求传递链很长,可以为请求的处理结果添加缓存,避免重复处理。
  • 提前终止链条:如果某个处理者已经完成了请求处理,可以选择终止责任链,避免继续传递。
    版权声明

7. 总结

责任链模式通过将请求传递给链中的多个处理者,让请求的处理变得灵活且可扩展。通过责任链,我们可以轻松添加或移除处理者,从而无需更改客户端代码。对于那些有多种不同处理方式的请求,责任链模式是一个非常有效的设计方案。

版权声明
  1. 本文内容属于原创,欢迎转载,但请务必注明出处和作者,尊重原创版权。
  2. 转载时,请附带原文链接并注明“本文作者:扣丁梦想家
  3. 禁止未经授权的商业转载。

如果您有任何问题或建议,欢迎留言讨论。

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

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

        相关文章

        【YOLOv8】损失函数

        学习视频&#xff1a; yolov8 | 损失函数 之 5、类别损失_哔哩哔哩_bilibili yolov8 | 损失函数 之 6、定位损失 CIoU DFL_哔哩哔哩_bilibili 2.13、yolov8损失函数_哔哩哔哩_bilibili YOLOv8 的损失函数由类别损失和定位损失构成 类别损失&#xff1a;BCE Loss 定位损失…

        【Linux】【网络】Libevent 内部实现简略版

        【Linux】【网络】Libevent 内部实现简略版 1 event_base结构–>相当于Reactor 在使用libevent之前&#xff0c;就必须先创建这个结构。 以epoll为例&#xff1a; 1.1evbase void* evbase-->epollop结构体&#xff08;以epoll为例&#xff09; libevent通过一个void…

        计算机网络抄手 运输层

        一、运输层协议概述 1. 进程之间的通信 从通信和信息处理的角度看&#xff0c;运输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。当网络边缘部分的两台主机使用网络核心部分的功能进行端到端的通信时&…

        MATLAB图像处理:图像分割方法

        图像分割将图像划分为具有特定意义的子区域&#xff0c;是目标检测、医学影像分析、自动驾驶等领域的核心预处理步骤。本文讲解阈值分割、边缘检测、区域生长、聚类分割、基于图的方法等经典与前沿技术&#xff0c;提供MATLAB代码实现。 目录 1. 图像分割基础 2. 经典分割方…

        【VSCode】MicroPython环境配置

        【VSCode】MicroPython环境配置 RT-Thread MicroPython 插件安装MicroPython 库文件配置结束语 RT-Thread MicroPython 插件安装 在 VSCode 拓展中搜索 “RT-Thread MicroPython” 并安装&#xff0c;详细配置步骤&#xff08;修改 VSCode 默认终端、MicroPython 代码补全&…

        【python】网页批量转PDF

        安装wkhtmltopdf 网站&#xff1a;wkhtmltopdf wkhtmltopdf http://www.baidu.com/ D:website1.pdf 安装pdfkit库 pip install pdfkit 批量转换代码 import os import pdfkit path_wkthmltopdf rE:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe config pdfkit.configu…

        基于Flask的租房信息可视化系统的设计与实现

        【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…

        Scrapy安装,创建Scrapy项目,启动Scrapy爬虫

        Scrapy安装&#xff0c;创建Scrapy项目&#xff0c;启动Scrapy爬虫 1. 安装 Python2. 安装 Scrapy3. 验证安装4. 创建 Scrapy 项目5. 启动爬虫5.1 示例 总结 Scrapy 的安装方式比较简单&#xff0c;下面是基于 Python 环境的安装流程&#xff1a; 1. 安装 Python 首先&#x…

        C++项目:高并发内存池_上

        目录 1. 项目介绍 2. 内存池概念 2.1 池化技术 2.2 内存池和内存碎片 2.3 细看malloc 3. 定长内存池的实现 ObjectPool.hpp 4. 高并发内存池框架 5. thread cache测试 5.1 thread cache框架 5.2 ConcurrentAlloc.hpp 6. central cache测试 6.1 central cache框架 …

        手机控制电脑远程关机

        远程看看软件兼容iOS和Android设备&#xff0c;该软件除了能通过电脑远程关闭另一台电脑外&#xff0c;您还可以通过它在手机上远程关闭公司的电脑。您可以按照以下步骤进行操作以实现电脑远程关机&#xff1a; 步骤1.在手机应用商店搜索“远程看看”进行软件安装&#xff0c;…

        IO模型与NIO基础--NIO网络传输选择器--字符编码

        放进NIO体系进行网络编程的工作流程&#xff1a; Selector的创建 通过调用Selector.open()方法创建一个Selector&#xff0c;如下&#xff1a; Selector selector Selector.open(); 向Selector注册通道 通过Channel.register()方法来实现&#xff0c; 注意&#xff1a;Chan…

        【亚马逊开发者账号02】终审问题SA+review_Pre-review+Doc.xlsx

        1.终审问题 你好感谢您在此过程中的回复和协作。所有想要构建具有受限 SP-API 角色的公开可用应用程序的开发人员都必须与我们的解决方案架构师团队一起完成架构审核。 这将需要详细说明应用程序的数据流、个人身份信息 &#xff08;PII&#xff09; 的数据保护控制&#xff0…

        c++标准io与线程,互斥锁

        封装一个 File 类&#xff0c; 用有私有成员 File* fp 实现以下功能 File f "文件名" 要求打开该文件 f.write(string str) 要求将str数据写入文件中 string str f.read(int size) 从文件中读取最多size个字节&#xff0c; 并将读取到的数据返回 析构函数 #…

        在高流量下保持WordPress网站的稳定和高效运行

        随着流量的不断增加&#xff0c;网站的稳定和高效运行变得越来越重要&#xff0c;特别是使用WordPress搭建的网站。流量过高时&#xff0c;网站加载可能会变慢&#xff0c;甚至崩溃&#xff0c;直接影响用户体验和网站正常运营。因此&#xff0c;我们需要采取一些有效的措施&am…

        Cython学习笔记1:利用Cython加速Python运行速度

        Cython学习笔记1&#xff1a;利用Cython加速Python运行速度 CythonCython 的核心特点&#xff1a;利用Cython加速Python运行速度1. Cython加速Python运行速度原理2. 不使用Cython3. 使用Cython加速&#xff08;1&#xff09;使用pip安装 cython 和 setuptools 库&#xff08;2&…

        web的分离不分离:前后端分离与不分离全面分析

        让我们一起走向未来 &#x1f393;作者简介&#xff1a;全栈领域优质创作者 &#x1f310;个人主页&#xff1a;百锦再新空间代码工作室 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[1504566…

        记录一个ES分词器不生效的解决过程

        问题背景 商城项目,其中商品查询检索使用的是ES, 但存在某些商品查询不到的问题 例如:某商品名包含AA_BBB这样的关键词,但是搜索"AA"不能查询到该商品,但是将商品名修改为AA BBB后就能查询到了. 怀疑是分词的问题,但看代码,在创建ES索引时在对应字段上也定义了分词器…

        高性能内存对象缓存Memcached详细实验操作

        目录 前提准备&#xff1a; cache1&#xff0c;2&#xff1a; 客户端cache-api&#xff08;一定得是LAMP环境&#xff09; memcache实现主主复制以及高可用(基于以上完成) cache1,2: memcachekeepalived(基于以上完成) cache1,2: 前提准备&#xff1a; 1. 准备三台cent…

        css之display:grid布局改块级元素布局

        1.问题&#xff1a; div是块级元素&#xff0c;一个div元素占一行&#xff0c;但是&#xff0c;今天测试样式时&#xff0c;总是会有两个div并占一行&#xff0c;很困惑&#xff0c;结果发现是app这个样式 在main.css里 #app样式布局在main.ts里被应用 2.原因以及样式分析 im…

        推荐一个github star45k+进阶的java项目及知识的网站

        mall是github上star 45k的一个java项目 mall项目是一套电商系统&#xff0c;包括前台商城系统及后台管理系统&#xff0c;基于SpringBootMyBatis实现&#xff0c;采用Docker容器化部署。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心…