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

设计模式 13 责任链模式

设计模式 13

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 13
    • 责任链模式(Chain of Responsibility Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 5 特点
      • 6 适用场景
      • 7 总结

责任链模式(Chain of Responsibility Pattern)

1 定义

责任链模式的核心思想是将请求沿着处理者链传递,直到其中一个处理者处理这个请求。这种模式的一个重要特性是:请求的发送者并不知道哪个对象会最终处理请求,系统中的处理者对象也无需知道其他处理者的结构,处理者之间的解耦提高了系统的灵活性。

2 结构

责任链模式包含以下角色:

  • 抽象处理者(Handler): 定义一个处理请求的接口,并且实现链中下一个处理者的引用。
  • 具体处理者(ConcreteHandler): 具体实现抽象处理者,处理请求或者将请求传递给链中的下一个处理者。
  • 客户端(Client): 负责将请求发送到链中的第一个处理者,通常不关心请求的最终处理者是谁。

UML 类图

+-----------------------------------+
|    Handler                        |  <----- 抽象处理者
+-----------------------------------+
| - next: Handler                   |  <----- 链中下一个处理者的引用
| + SetNext(handler: Handler)       |
| + HandleRequest(request: Request) |
+-----------------------------------+
        ^
        |
+-----------------------------------+    +-----------------------------------+
|  ConcreteHandler1                 |    |  ConcreteHandler2                 |
+-----------------------------------+    +-----------------------------------+
| + HandleRequest(request: Request) |    | + HandleRequest(request: Request) |
+-----------------------------------+    +-----------------------------------+

3 示例代码

假设我们有一个支持多级审批的系统,每个级别的审批员处理不同级别的请求。请求可以从一个审批员传递到下一个审批员,直到某个审批员处理了请求或者请求被拒绝。

抽象处理者

// 抽象处理者
public abstract class Approver
{
    protected Approver _nextApprover;

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

    public abstract void ProcessRequest(PurchaseRequest request);
}

具体处理者

// 具体处理者1:经理
public class Manager : Approver
{
    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 10000)
        {
            Console.WriteLine($"{this.GetType().Name} approved request# {request.Number}");
        }
        else if (_nextApprover != null)
        {
            _nextApprover.ProcessRequest(request);
        }
    }
}

// 具体处理者2:总监
public class Director : Approver
{
    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 25000)
        {
            Console.WriteLine($"{this.GetType().Name} approved request# {request.Number}");
        }
        else if (_nextApprover != null)
        {
            _nextApprover.ProcessRequest(request);
        }
    }
}

// 具体处理者3:副总裁
public class VicePresident : Approver
{
    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 50000)
        {
            Console.WriteLine($"{this.GetType().Name} approved request# {request.Number}");
        }
        else if (_nextApprover != null)
        {
            _nextApprover.ProcessRequest(request);
        }
    }
}

// 具体处理者4:总裁
public class President : Approver
{
    public override void ProcessRequest(PurchaseRequest request)
    {
        if (request.Amount < 100000)
        {
            Console.WriteLine($"{this.GetType().Name} approved request# {request.Number}");
        }
        else
        {
            Console.WriteLine($"Request# {request.Number} requires an executive meeting!");
        }
    }
}

请求类

// 请求类:采购请求
public class PurchaseRequest
{
    public int Number { get; }
    public double Amount { get; }
    public string Purpose { get; }

    public PurchaseRequest(int number, double amount, string purpose)
    {
        Number = number;
        Amount = amount;
        Purpose = purpose;
    }
}

客户端代码

class Program
{
    static void Main(string[] args)
    {
        // 创建处理者对象
        Approver manager = new Manager();
        Approver director = new Director();
        Approver vp = new VicePresident();
        Approver president = new President();

        // 设置责任链
        manager.SetNext(director);
        director.SetNext(vp);
        vp.SetNext(president);

        // 创建多个采购请求
        PurchaseRequest request1 = new PurchaseRequest(1, 5000, "Buy supplies");
        PurchaseRequest request2 = new PurchaseRequest(2, 20000, "Buy projectors");
        PurchaseRequest request3 = new PurchaseRequest(3, 35000, "Buy laptops");
        PurchaseRequest request4 = new PurchaseRequest(4, 90000, "Buy servers");

        // 处理请求
        manager.ProcessRequest(request1);
        manager.ProcessRequest(request2);
        manager.ProcessRequest(request3);
        manager.ProcessRequest(request4);
    }
}

运行结果

Manager approved request# 1
Director approved request# 2
VicePresident approved request# 3
President approved request# 4

在这个例子中,ManagerDirectorVicePresidentPresident 这四个处理者构成了一个责任链。每个处理者都检查请求的金额,并决定是否可以处理请求,如果不能处理则将请求传递给下一个处理者。

5 特点

  • 优点:

    • 降低耦合度: 客户端不需要知道哪个处理者会最终处理请求,这使得系统更灵活、可扩展。

    • 增加灵活性: 可以动态地添加或移除处理者,甚至可以动态调整处理者链的顺序。

    • 职责分离: 每个处理者只关注自己能够处理的那部分职责,符合单一职责原则。

  • 缺点:

    • 不保证请求被处理: 如果链上的处理者都不能处理请求,那么请求可能会被丢弃。

    • 可能影响性能: 如果责任链过长,或者某些处理者链路中的节点过多,可能导致请求处理的延迟。

6 适用场景

  • 多个对象可以处理同一请求: 比如事件处理系统、请求处理链。
  • 请求的处理需要动态指定: 比如审批流程中的不同审批级别。
  • 需要在不明确接收者的情况下发送请求: 客户端不需要知道具体是哪个对象处理了请求。

7 总结

责任链模式通过将处理者对象串联成一条链,使请求能够沿着链传递,直到被某个处理者处理。这种模式的灵活性使其适用于多种场景,尤其是那些需要动态指定请求处理者或处理者职责可能发生变化的场合。


http://www.kler.cn/news/283399.html

相关文章:

  • 搭建webRTC cotrun流媒体服务器
  • Python中的命令模式:如何设计灵活的命令体系
  • Redis持久化方式、常见问题及解决方案
  • centos安装docker并配置加速器
  • Keil5 Debug模式Watch窗口添加的监控变量被自动清除
  • 【智能算法改进】多策略融合的改进黑猩猩搜索算法及其应用
  • 备忘录模式 详解
  • 电脑强制退出程序快捷键
  • pytorch交叉熵损失函数
  • 效果媲美GPT4V的多模态大型语言模型MiniCPM-V-2_6详细介绍
  • 数据结构(邓俊辉)学习笔记】串 03——KMP算法:记忆法
  • python批量生成sql用于创建500个用户
  • 从数据库中查找单词
  • JAVA电子器件制造行业生产管理系统计算机毕设计算机毕业设计
  • 2024.8.30(使用docker部署project-exam-system)
  • 20.神经网络 - 搭建小实战和 Sequential 的使用
  • 自动化数据汇总:使用Python从多个数据源汇总数据
  • linux查找mysql日志
  • 艾体宝干货丨Redis与MongoDB的区别
  • 自动化通过cmd命令行并以特定账户连接到远程机器
  • 【香橙派系列教程】(二十一) 基于OrangePi Zero2的系统移植— 交叉编译工具链配置
  • 【C++ 面试 - 内存管理】每日 3 题(九)
  • 算法中常用的排序
  • 云计算实训37——Dockerfile的应用+私有仓库的创建与管理
  • 更改图片中的部分颜色及修改图片的背景色
  • 如何知道当前网卡连接的下位机的IP,通过工具实现
  • 代码随想录 | 贪心算法总结
  • 负载均衡OJ项目详细解剖
  • Error running tomcat: Can‘t find catalina.jar
  • 给自己复盘的随想录笔记-哈希表