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

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

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


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

二、模式结构

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

  1. Handler(抽象处理者)

    定义一个接口,声明处理请求的方法,以及一个引用指向下一个处理者。

  2. ConcreteHandler(具体处理者)

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

  3. Client(客户端)

    创建并配置责任链,并向链的起点发出请求。


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

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

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

  • 如果报销金额小于 1000 元,由经理审批。
  • 如果金额在 1000 元到 5000 元之间,由总监审批。
  • 如果金额超过 5000 元,由副总裁审批。
2. 实现代码
csharp 复制代码
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. 权限验证:多级权限验证链,根据用户角色处理请求。

八、总结

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

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

相关推荐
千千寰宇5 小时前
[设计模式/Java/多线程] 设计模式之单例模式【9】
设计模式·操作系统-进程/线程/并发
此木|西贝12 小时前
【设计模式】原型模式
java·设计模式·原型模式
“抚琴”的人12 小时前
【机械视觉】C#+VisionPro联合编程———【六、visionPro连接工业相机设备】
c#·工业相机·visionpro·机械视觉
FAREWELL0007514 小时前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
CodeCraft Studio14 小时前
Excel处理控件Spire.XLS系列教程:C# 合并、或取消合并 Excel 单元格
前端·c#·excel
勘察加熊人16 小时前
forms实现连连看
c#
hvinsion16 小时前
PPT助手:一款集计时、远程控制与多屏切换于一身的PPT辅助工具
c#·powerpoint·ppt·ppt助手·ppt翻页
weixin_3077791317 小时前
使用C#实现从Hive的CREATE TABLE语句中提取分区字段名和数据类型
开发语言·数据仓库·hive·c#
时光追逐者18 小时前
在 Blazor 中使用 Chart.js 快速创建数据可视化图表
开发语言·javascript·信息可视化·c#·.net·blazor
高 朗19 小时前
2025高频面试设计模型总结篇
设计模式·面试·职场和发展