设计模式之 责任链模式

news2024/11/28 2:50:27

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在将多个处理对象通过链式结构连接起来,形成一条处理请求的链条。每个处理对象都有机会处理请求,或者将请求传递给链中的下一个对象。这样,客户端不需要知道哪个具体的对象会处理请求,而是通过责任链的结构来自动地传递和处理请求。

责任链模式的核心思想是将处理请求的职责链式连接起来,由链中的对象依次处理请求,直到某个对象处理完请求为止。

一、责任链模式的组成部分

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

  1. Handler(处理者接口)

    定义了一个接口,声明了处理请求的方法。在该方法中,处理者通常会选择是否处理请求。如果能够处理,则处理请求,否则将请求转发给下一个处理者。
  2. ConcreteHandler(具体处理者)

    实现了Handler接口,定义了具体的处理逻辑。如果该对象能够处理请求,则直接处理;如果不能处理,则将请求传递给下一个处理者。
  3. Client(客户端)

    负责初始化责任链,并向链中的第一个处理者发送请求。客户端不需要关心请求是由哪一个处理者来完成的。
  4. Chain(责任链)

    由多个处理者对象组成。每个处理者对象都有一个指向下一个处理者的引用。请求会沿着责任链逐一传递,直到有处理者处理请求或者链的末尾。
二、责任链模式的工作原理

责任链模式的工作原理是将多个处理对象组成链条,每个处理对象知道下一个处理对象,并负责将请求转发给下一个对象。每个处理者对象会判断自己是否能够处理请求,如果可以处理请求,则执行相应的操作;如果不可以处理请求,则将请求转发给责任链中的下一个处理者。

这种设计模式非常适合处理多个处理条件之间的连贯流程,例如:请求审批流程、日志记录、事件处理等。

三、责任链模式的代码示例
  • 定义抽象处理者
    public abstract class Handler{
    
        protected Handler nextHandler;
    
        public abstract void setNext(Handler handler);
    
        public abstract void handleRequest(int request);
    }
  • 定义具体的处理者
    public class GroupHandler extends Handler{
    
        @Override
        public void setNext(Handler handler) {
            nextHandler = handler;
        }
    
    
        @Override
        public void handleRequest(int request) {
            if (request < 3){
                System.out.println("小组长批准"+request+"天假");
            }else {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    public class Manager extends Handler{
    
        @Override
        public void setNext(Handler handler) {
            nextHandler = handler;
        }
    
        @Override
        public void handleRequest(int request) {
            if (request < 5){
                System.out.println("经理批准"+request+"天假");
            }else {
                nextHandler.handleRequest(request);
            }
        }
    }
    
    public class GeneralManager extends Handler{
    
        @Override
        public void setNext(Handler handler) {
            throw new RuntimeException("总经理是最高职位");
        }
    
        @Override
        public void handleRequest(int request) {
            if (request < 10){
                System.out.println("总经理批准"+request+"天假");
            }
        }
    }
    
  • 客户端代码
    public class Client {
        public static void main(String[] args) {
            GroupHandler groupHandler = new GroupHandler();
            Manager manager = new Manager();
            GeneralManager generalManager = new GeneralManager();
            groupHandler.setNext(manager);
            manager.setNext(generalManager);
            //请四天假
            groupHandler.handleRequest(4);
        }
    }
  • 运行结果
四、责任链模式的优缺点
优点:
  1. 解耦请求发送者与处理者:客户端不需要知道哪个处理者会处理请求,只需要发起请求即可,责任链的结构内部决定了请求的处理流程。
  2. 降低了对象之间的耦合度:每个处理者仅仅负责判断请求是否能处理,并将无法处理的请求传递给下一个处理者。这样,系统中的对象之间的依赖关系大大减少。
  3. 增强灵活性和扩展性:责任链中的每个处理者都可以独立扩展,可以通过增加新的处理者来修改或扩展请求处理的逻辑,而不需要修改现有的代码。
  4. 动态控制请求的处理流程:请求的处理可以动态改变,可以控制责任链的顺序,或者在运行时选择是否将请求传递给下一个处理者。
缺点:
  1. 性能开销:如果责任链较长,且每个请求都需要经过多个处理者,可能会导致性能问题,因为每个请求都需要被逐个检查和转发。
  2. 调试难度:由于请求可能会经过多个处理者,这种链式的调用可能会增加调试的难度,尤其是在请求的处理过程非常复杂时,调试和跟踪问题可能会变得更加困难。
  3. 请求处理不明确:如果没有明确的设计,责任链中的某个请求可能会一直传递下去,直到链的最后也没有处理,从而可能导致请求的处理不及时,或者被忽略。
五、责任链模式的应用场景

责任链模式适用于以下几种场景:

  1. 多层次的请求处理

    当有多个处理对象需要依次处理同一个请求时,责任链模式非常适用。例如,权限验证、审批流程等需要经过多个步骤的处理。
  2. 动态改变请求的处理顺序

    通过灵活配置责任链,可以动态改变请求的处理顺序,而无需修改客户端的代码。例如,在一些复杂的系统中,根据不同的配置,可能会根据不同的规则选择不同的处理链。
  3. 日志处理系统

    责任链模式非常适合用于日志系统,不同的日志处理器(如文件日志、数据库日志、网络日志等)可以按顺序处理日志请求。如果一个处理器无法处理日志,可以将其传递给下一个处理器。
  4. 事件处理系统

    在事件驱动的系统中,可以使用责任链模式来分发和处理事件。事件可以依次传递给多个处理者,每个处理者可以根据自己的条件决定是否处理该事件。
  5. 权限验证

    • 在系统中的权限控制过程中,可能会有多个权限验证步骤,责任链模式可以通过设置多个权限验证处理者来实现逐步验证,直到请求满足某个权限要求。

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

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

相关文章

新版布谷直播软件源码开发搭建功能更新明细

即将步入2025年也就是山东布谷科技专注直播系统开发,直播软件源码出售开发搭建等业务第9年,山东布谷科技不断更新直播软件功能&#xff0c;以适应当前新市场环境下的新要求。山东布谷科技始终秉承初心&#xff0c;做一款符合广大客户需求的直播系统软件。支持广大客户提交更多个…

VITE+VUE3+TS环境搭建

前言&#xff08;与搭建项目无关&#xff09;&#xff1a; 可以安装一个node管理工具&#xff0c;比如nvm&#xff0c;这样可以顺畅的切换vue2和vue3项目&#xff0c;以免出现项目跑不起来的窘境。我使用的nvm&#xff0c;当前node 22.11.0 目录 搭建项目 添加状态管理库&…

HTML飞舞的爱心

目录 系列文章 写在前面 完整代码 代码分析 写在后面 系列文章 序号目录1HTML满屏跳动的爱心&#xff08;可写字&#xff09;2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心&#xff08;简易版&#xff09;7HTML粒子爱心8HTML蓝色…

英伟达推出了全新的小型语言模型家族——Hymba 1.5B

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

低速接口项目之串口Uart开发(二)——FIFO实现串口数据的收发回环测试

本节目录 一、设计思路 二、loop环回模块 三、仿真模块 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计思路 串口数据的收发回环测试&#xff0c;最简单的硬件测试是把Tx和Rx连接在一起&#xff0c;然后上位机进行发送和接收测试&#xff0c;但是需要考虑到串…

《Java核心技术I》树集

树集 TreeSet类与散列类似&#xff0c;树集是一个有序集合(sorted collection)。 可以以任意顺序将元素插入到集合中&#xff0c;遍历集合时&#xff0c;自动按照排序后的顺序呈现。 插入5个字符串&#xff0c;访问添加的元素 package treeSet;import java.util.TreeSet;pu…

Tailwind CSS v4.0 开启

Tailwind CSS v4.0 发布了 Tailwind CSS 是一个为快速开发而精心设计的原子类 CSS 框架&#xff0c;它提供了充满设计感和应用程序至上的能力来创建组件&#xff0c;它在最新的 2.0 版本中加入了暗黑模式&#xff0c;开箱即用。 Tailwind Connect 大会上&#xff0c;与会者抢先…

QML TableView 实例演示 + 可能遇到的一些问题(Qt_6_5_3)

一、可能遇到的一些问题 Q1&#xff1a;如何禁用拖动&#xff1f; 在TableView下加一句代码即可&#xff1a; interactive: false 补充&#xff1a;这个属性并不专属于TableView&#xff0c;而是一个通用属性。很多Controls下的控件都可以使用&#xff0c;其主要作用就是控…

详细描述一下Elasticsearch更新和删除文档的过程?

大家好&#xff0c;我是锋哥。今天分享关于【详细描述一下Elasticsearch更新和删除文档的过程&#xff1f;】面试题。希望对大家有帮助&#xff1b; 详细描述一下Elasticsearch更新和删除文档的过程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 E…

(五)Ubuntu22.04+Stable-Diffusion-webui AI绘画 模型转换插件安装及其使用

一、说明 这是秋叶大佬开发的一个模型转换插件&#xff0c;秋叶整合包中自带。如果你的 Stable Diffusion WebUI 中没有这个插件&#xff0c;请使用下面这个地址安装&#xff0c;安装完成之后别忘了重启 WebUI。 模型转换插件 https://github.com/Akegarasu/sd-webui-model-c…

Python数据分析实例五、US 大选捐款数据分析

美国联邦选举委员会 (FEC) 公布了对政治竞选活动的贡献数据。这包括投稿人姓名、职业和雇主、地址和投款金额。2012 年美国总统大选的贡献数据以单个 150 MB 的 CSV 文件P00000001-ALL.csv形式提供,该文件可以通过以下pandas.read_csv加载: import pandas as pdfec = pd.r…

原生微信小程序画表格

wxml部分&#xff1a; <view class"table__scroll__view"><view class"table__header"><view class"table__header__item" wx:for"{{TableHeadtitle}}" wx:key"index">{{item.title}}</view></…

TCP/IP协议攻击与防范

一、TCP/IP协议攻击介绍 1.1 Internet的结构​ LAN&#xff1a;局域网 WAN&#xff1a;广域网 WLAN&#xff1a;无线局域网 私有IP地址与公有IP地址&#xff1f; 私有地址&#xff1a;A类&#xff1a;10.0.0.0~10.255.255.255 B类&#xff1a;172.16.0.0~172.31.255.255…

微信小程序2-地图显示和地图标记

一、index修改页面&#xff0c;让页面能够显示地图和一个添加标记的按钮。 index.wxml <scroll-view class"scrollarea" scroll-y type"list"><view class"index_container"><map id"map" style"width: 100%; h…

【C++】从C语言到C++学习指南

如果你也是从C语言一路过来的&#xff0c;那么请一起看下去吧&#xff01; 文章目录 面型对象程序设计C基础C和C一些语法区别C在非对象方面对C语言的扩充C的一些标准&#xff08;兼容旧标准&#xff09; 首先&#xff0c;在C的学习中&#xff0c;我们要时刻清醒一点&#xff1…

Fakelocation Server服务器/专业版 ubuntu

前言:需要Ubuntu系统 Fakelocation开源文件系统需求 Ubuntu | Fakelocation | 任务一 任务一 更新Ubuntu&#xff08;安装下载不再赘述&#xff09; sudo -i # 提权 sudo apt update # 更新软件包列表 sudo apt upgrade # 升级已安装的软…

探索Python的HTTP之旅:揭秘Requests库的神秘面纱

文章目录 **探索Python的HTTP之旅&#xff1a;揭秘Requests库的神秘面纱**第一部分&#xff1a;背景介绍第二部分&#xff1a;Requests库是什么&#xff1f;第三部分&#xff1a;如何安装Requests库&#xff1f;第四部分&#xff1a;Requests库的五个简单函数使用方法第五部分&…

WPF——ICON按钮制作

前言 首先ICON按钮&#xff0c;即带图标按钮&#xff0c;即图标按钮。 图标按钮在开发时&#xff0c;主要是有两种方式来进行。一是在Button的Content内添加Image&#xff0c;然后设置Image的属性Source来实现&#xff0c;这种方式主要是简单易操作&#xff0c;对于初学者来说…

【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

三开关VUE组件

一、使用效果 <template><QqThreeSwitch v-model"value" /><!-- <SqThreeSwitch v-model"value" :options"[test1, test2, test3]"><template #left-action><div style"display: flex"><IconMoon…