设计模式 13 责任链模式

设计模式 13

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

文章目录

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

责任链模式(Chain of Responsibility Pattern)

1 定义

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

2 结构

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

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

UML 类图

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

3 示例代码

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

抽象处理者

csharp 复制代码
// 抽象处理者
public abstract class Approver
{
    protected Approver _nextApprover;

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

    public abstract void ProcessRequest(PurchaseRequest request);
}

具体处理者

csharp 复制代码
// 具体处理者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!");
        }
    }
}

请求类

csharp 复制代码
// 请求类:采购请求
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;
    }
}

客户端代码

csharp 复制代码
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);
    }
}

运行结果

plaintext 复制代码
Manager approved request# 1
Director approved request# 2
VicePresident approved request# 3
President approved request# 4

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

5 特点

  • 优点:

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

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

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

  • 缺点:

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

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

6 适用场景

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

7 总结

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

相关推荐
-凌凌漆-1 小时前
【设计模式】装饰模式
设计模式
蔚一1 小时前
Java设计模式—面向对象设计原则(一) ----->开闭原则OCP(完整详解,附有代码+案例)
java·后端·设计模式·intellij-idea·开闭原则
丶白泽4 小时前
重修设计模式-结构型-代理模式
设计模式·系统安全·代理模式
Java__攻城狮6 小时前
java设计模式(持续更新中)
java·开发语言·设计模式
王佑辉6 小时前
【软考】设计模式之抽象工厂模式
设计模式·软考
会敲代码的小张6 小时前
设计模式-外观模式
java·开发语言·后端·设计模式·外观模式
AI让世界更懂你7 小时前
漫谈设计模式 [9]:外观模式
python·设计模式·外观模式
LB_bei10 小时前
设计模式-行为型模式-备忘录模式
设计模式·备忘录模式
心之语歌11 小时前
设计模式 桥接模式(Bridge Pattern)
java·设计模式·桥接模式
LB_bei13 小时前
设计模式-行为型模式-访问者模式
设计模式·访问者模式