C# 设计模式(行为型模式):责任链模式

C# 设计模式(行为型模式):责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于让多个对象有机会处理同一个请求,避免请求发送者与接收者之间的耦合。它通过将请求沿着一条链传递,直到某个对象处理它,从而实现了请求和处理者的动态解耦。


一、责任链模式的核心概念
  1. 请求传递:将请求从一个对象传递到下一个对象,直到找到能够处理请求的对象为止。
  2. 职责分离:每个对象专注于处理自己的职责,其他职责交由链上的其他对象处理。
  3. 动态链条:链条的结构可以动态调整,灵活扩展。

二、模式结构

在责任链模式中,通常包含以下角色:

  1. Handler(抽象处理者)
    定义一个接口,声明处理请求的方法,以及一个引用指向下一个处理者。

  2. ConcreteHandler(具体处理者)
    实现抽象处理者接口,负责处理具体的请求。如果不能处理,则将请求传递给下一个处理者。

  3. Client(客户端)
    创建并配置责任链,并向链的起点发出请求。


三、适用场景
  • 职责分散:需要将职责分散到多个对象中,以便降低耦合度。
  • 动态处理:某些请求需要灵活地由不同的对象处理。
  • 多级审批:如审批系统、权限管理等需要逐级处理的场景。

四、C# 实现案例
1. 场景描述

假设一个公司有以下审批流程:

  • 如果报销金额小于 1000 元,由经理审批。
  • 如果金额在 1000 元到 5000 元之间,由总监审批。
  • 如果金额超过 5000 元,由副总裁审批。
2. 实现代码
using System;

namespace ChainOfResponsibilityExample
{
    // 抽象处理者
    abstract class Approver
    {
        protected Approver NextApprover;

        public void SetNext(Approver nextApprover)
        {
            NextApprover = nextApprover;
        }

        public abstract void HandleRequest(PurchaseRequest request);
    }

    // 具体处理者:经理
    class Manager : Approver
    {
        public override void HandleRequest(PurchaseRequest request)
        {
            if (request.Amount < 1000)
            {
                Console.WriteLine($"经理批准了金额为 {request.Amount} 元的请求。");
            }
            else if (NextApprover != null)
            {
                NextApprover.HandleRequest(request);
            }
        }
    }

    // 具体处理者:总监
    class Director : Approver
    {
        public override void HandleRequest(PurchaseRequest request)
        {
            if (request.Amount >= 1000 && request.Amount <= 5000)
            {
                Console.WriteLine($"总监批准了金额为 {request.Amount} 元的请求。");
            }
            else if (NextApprover != null)
            {
                NextApprover.HandleRequest(request);
            }
        }
    }

    // 具体处理者:副总裁
    class VicePresident : Approver
    {
        public override void HandleRequest(PurchaseRequest request)
        {
            if (request.Amount > 5000)
            {
                Console.WriteLine($"副总裁批准了金额为 {request.Amount} 元的请求。");
            }
            else if (NextApprover != null)
            {
                NextApprover.HandleRequest(request);
            }
        }
    }

    // 请求类
    class PurchaseRequest
    {
        public double Amount { get; }

        public PurchaseRequest(double amount)
        {
            Amount = amount;
        }
    }

    // 客户端
    class Program
    {
        static void Main(string[] args)
        {
            // 构建责任链
            Approver manager = new Manager();
            Approver director = new Director();
            Approver vicePresident = new VicePresident();

            manager.SetNext(director);
            director.SetNext(vicePresident);

            // 模拟请求
            var request1 = new PurchaseRequest(500);
            var request2 = new PurchaseRequest(3000);
            var request3 = new PurchaseRequest(10000);

            manager.HandleRequest(request1);
            manager.HandleRequest(request2);
            manager.HandleRequest(request3);
        }
    }
}

五、运行结果

执行上述代码后,输出如下:

经理批准了金额为 500 元的请求。
总监批准了金额为 3000 元的请求。
副总裁批准了金额为 10000 元的请求。

六、优缺点分析
优点
  1. 解耦请求与处理者:发送者无需知道具体的处理者是谁,减少了系统耦合。
  2. 职责分离:每个处理者只需专注于自己的职责,代码清晰易维护。
  3. 易于扩展:可以轻松添加新的处理者,调整链条结构。
缺点
  1. 可能无处理者响应:如果链的末端没有处理请求的逻辑,可能导致请求丢失。
  2. 性能开销:请求需要沿着链传递,链条过长可能影响性能。

七、实际应用场景
  1. 审批流程:多级审批系统中,每个级别的管理者负责不同金额范围的审批。
  2. 日志处理:不同级别的日志可以由不同的处理器记录(如控制台、文件或远程服务器)。
  3. 权限验证:多级权限验证链,根据用户角色处理请求。

八、总结

责任链模式是一种优雅的设计模式,适用于需要动态分配职责的场景。通过它,可以实现请求发送者与处理者的解耦,使系统具有更好的扩展性和灵活性。如果你正在设计一个多级处理的系统,不妨试试责任链模式!

希望这篇文章能帮助你更好地理解责任链模式!如果有疑问或建议,欢迎在评论区留言 😊

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网关的主要类型和它们的特点

网关&#xff0c;作为网络通信的关键节点&#xff0c;根据其应用场景和功能特点&#xff0c;可以分为多种类型。 1.协议网关 特点&#xff1a; • 协议转换&#xff1a;协议网关的核心功能是转换不同网络之间的通信协议。例如&#xff0c;它可以将IPv4协议的数据包转换为IPv6协…

JAVA学习笔记_JVM

文章目录 初识jvm内存结构程序计数器(寄存器) 栈问题辨析内存溢出 线程诊断本地方法栈Heap堆内存溢出内存诊断 方法区内存溢出常量池 stringTable直接内存垃圾回收 初识jvm JRE JVM 基础类库 JDK JRE 编译工具 JavaSE JDK IDE工具 JavaEE JDK 应用服务器 IDE工具 jvm是…

无线AP安装注意事项

现在的办公楼、酒店等项目中都设计含有网络无线覆盖这一项&#xff0c;在项目实施中&#xff0c;往往采用的是便捷并且后期便于网络无线设备管理的无线ap设备&#xff0c;作为前端无线信号的覆盖。在具体安装无线AP过程中&#xff0c;我们必须要注意以下几点才能保证项目实施完…

PHP框架+gatewayworker实现在线1对1聊天--聊天界面布局+创建websocket连接(5)

文章目录 聊天界面布局html代码 创建websocket连接为什么要绑定&#xff1f; 聊天界面布局 在View/Index目录下创建index.html html代码 <div id"chat"><div id"nbar"><div class"pull-left">与牛德胜正在聊天...</div…

毕设中所学

1、交叉引用 在毕业设计论文Word中交叉引用参考文献_交叉引用如何标注[1~6]-CSDN博客 另&#xff1a;将标号或其他文字改为上标的快捷键是CtrlShift。 图的交叉引用一样&#xff0c;修改引用类型即可。 2、ENVI安装 ENVI5.6 安装教程&#xff0c;新手入门&#xff08;超详细…

xilinx的高速接口构成原理和连接结构及ibert工具的使用-以k7 GTX为例

一、相关简介 Xilinx的高速接口称之为transceivers(高速收发器&#xff09;&#xff0c;这部分的电路是专用电路&#xff0c;供电等都是独立的&#xff0c;根据速率可以分为GTP/GTX/GTH/GTY/GTM等。 Xilinx的高速接口是QUAD为单位的&#xff0c;没一个QUAD由一个时钟COMMON资…

Formality:官方Tutorial(一)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 本文是对Synopsys Formality User Guide Tutorial中第一个实验的翻译&#xff08;有删改&#xff09;&#xff0c;Lab文件可以从以下链接获取。 Formality官方Tu…

【openwrt】OpenWrt 路由器的 802.1X 动态 VLAN

参考链接 [OpenWrt Wiki] Wi-Fi /etc/config/wirelesshttps://openwrt.org/docs/guide-user/network/wifi/basic#wpa_enterprise_access_point 介绍 基于802.1X 无线网络身份验证࿰

Mac 环境 VVenC 编译与编码命令行工具使用教程

VVenC VVenC 是一个开源的高效视频编码器&#xff0c;专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准&#xff0c;主要目的是提供比 HEVC 更高的压缩效率&#xff0c;同时保持或提高视频质量。H.266/VVC…

wx016基于springboot+vue+uniapp的超市购物系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

RTC:实时时钟

RTC&#xff1a;实时时钟 1、实时时钟2、闹钟中断3、秒中断4、输出功能5、BKP的读写6、BKP的侵入事件 1、实时时钟 ①RTC.c #include "RTC.h"/*** brief&#xff1a;RTC初始化函数*/ RCC_PeriphCLKInitTypeDef RTCPeriphClkInit; //RTC时钟配置结构体 RTC_HandleT…

黑马JavaWeb开发跟学(十五).Maven高级

黑马JavaWeb开发跟学.十五.Maven高级 Maven高级1. 分模块设计与开发1.1 介绍1.2 实践1.2.1 分析1.2.2 实现 1.3 总结 2. 继承与聚合2.1 继承2.1.1 继承关系2.1.1.1 思路分析2.1.1.2 实现 2.1.2 版本锁定2.1.2.1 场景2.1.2.2 介绍2.1.2.3 实现2.1.2.4 属性配置 2.2 聚合2.2.1 介…

cka考试-03-k8s版本升级

一、原题 二、解答 [root@master ~]# kubectl get node NAME STATUS ROLES AGE VERSION master Ready control-plane,master 25h v1.22.12 node1 Ready worker 25h v1.22.12 node2 Ready worker …

【Java项目】基于SpringBoot的【垃圾分类系统】

【Java项目】基于SpringBoot的【垃圾分类系统】 技术简介&#xff1a;本系统使用采用B/S架构、Spring Boot框架、MYSQL数据库进行开发设计。 系统简介&#xff1a;使用者分为管理员和用户、垃圾分类管理员&#xff0c;实现功能包括管理员&#xff1a;首页、个人中心、用户管理、…

文本区域提取和分析——Python版本

目录 1. 图像预处理 2. 文本区域提取 3. 文本行分割 4. 文本区域分析 5. 应用举例 总结 文本区域提取和分析是计算机视觉中的重要任务&#xff0c;尤其在光学字符识别&#xff08;OCR&#xff09;系统、文档分析、自动化数据录入等应用中有广泛的应用。其目标是从图像中提…

华为的数字化转型框架和数字化转型成熟度评估方法

2016年&#xff0c;华为公司数字化转型变革规划汇报通过&#xff0c;一系列的变革项目由变革指导委员会(Executive Steering Committee,ESC)完成立项。8年多来&#xff0c;华为数字化转型工作初步取得了一些成果&#xff0c;比如&#xff1a; 实现“销售收入翻番&#xff0c;但…

算法 Class 006(二分搜索)

一、查找一个数 在一个有序数组中查找数字&#xff0c;每次一循环可 砍掉一半的值&#xff0c;只要确定了 arr[mid] 与 num 之间的关系。 大于num 忽略掉 mid及右边的数字 小于 num 忽略掉 mid 及左边的数字 二、 找大于等于 num 的最左位置 意思就是该下标及右边的数都是大于…

【工具整理】WIN换MAC机器使用工具整理

最近公司电脑升级&#xff0c;研发同学统一更换了 Mac Book Pro 笔记版电脑&#xff0c;整理一下安装了那些软件以及出处&#xff0c;分享记录下&#xff5e; 知识库工具 1、语雀 网址&#xff1a;语雀&#xff0c;为每一个人提供优秀的文档和知识库工具 语雀 个人花园&…

EdgeX规则引擎eKuiper

EdgeX 规则引擎eKuiper 一、架构设计 LF Edge eKuiper 是物联网数据分析和流式计算引擎。它是一个通用的边缘计算服务或中间件,为资源有限的边缘网关或设备而设计。 eKuiper 采用 Go 语言编写,其架构如下图所示: eKuiper 是 Golang 实现的轻量级物联网边缘分析、流式处理开源…

Python脚本实现通过Vector VN1630A CAN盒子与ECU通信

1 安装 python-can 包 安装命令如下&#xff1a; pip install python-can安装完成后可用下面命令查看是否安装成功及版本。 pip show python-canName: python-can Version: 4.4.2 Summary: Controller Area Network interface module for Python Home-page: https://github.…