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

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. 权限验证:多级权限验证链,根据用户角色处理请求。

八、总结

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

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


http://www.kler.cn/a/464971.html

相关文章:

  • 约瑟夫问题
  • java项目之社区医院信息平台源码(springboot+mysql)
  • 如何判断状态:停留还是移动。【计算加速度de方案】
  • PTA数据结构作业一
  • Git快速入门(三)·远程仓库GitHub以及Gitee的使用
  • seata分布式事务详解(AT)
  • 分布式微服务项目___某污水处理项目
  • Cornerstone3D:快速搭建可以读取本地文件且四视图显示的Nifti Viewer
  • golang后台框架总结
  • 计算机网络 (19)扩展的以太网
  • Centos 7.6 安装mysql 5.7
  • 静态库封装之ComDir类
  • 数据仓库建设方案和经验总结
  • 【Hackthebox 中英 Write-Up】Web Request | 分析 HTTP 请求和响应
  • C++高级编程技巧:模板元编程与性能优化实践
  • php Yii2 execl表格导出样式定义
  • 【ArcGISPro/GeoScenePro】解决常见的空间参考和投影问题
  • 并发编程系列(三) -synchronized关键字介绍
  • docker 部署nginx
  • 掌握 Dockerfile:格式、解析器指令、环境变量替换
  • uwsgi中指定了uid为nginx,通过subprocess调用conda时候仍尝试读取/root/.config/conda/.condarc
  • Tailwind CSS 实战:响应式布局最佳实践
  • Python从0到100(八十一):神经网络-Fashion MNIST数据集取得最高的识别准确率
  • CSS 学习之 padding 与图形绘制
  • 实训四 :磁盘管理
  • .net core 依赖注入 Dependency Injection, DI