责任链模式(ChainofResponsibilityPattern)

1.定义

允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
在这里插入图片描述

2.结构

在这里插入图片描述

  • 处理者(Handler):声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。
  • 基础处理者(Base Handler):是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。
    通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。
  • 具体处理者(Concrete Handlers) :包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
    处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
  • 客户端 (Client):可根据程序逻辑一次性或者动态地生成链。 值得注意的是, 请求可发送给链上的任意一个处理者, 而非必须是第一个处理者。

3.问题描述

    以公司采购东西为例子来实现责任链模式。公司规定:

  • 采购总价 < 10000.0,处理人:经理(Manager)
  • 10000.0 < 采购总价 < 25000.0,处理人:副总(VicePresident)
  • 25000.0 < 采购总价 < 100000.0,处理人:总经理(President)

    对于这样一个需求,最直观的方法就是设计一个方法,参数是采购的总价,然后在这个方法内对价格进行调整判断,然后针对不同的条件交给不同级别的人去处理,这样确实可以解决问题,但这样一来,我们就需要多重if-else语句来进行判断,但当加入一个新的条件范围时,我们又不得不去修改原来设计的方法来再添加一个条件判断,这样的设计显然违背了“开-闭”原则。这时候,可以采用责任链模式来解决这样的问题。

代码实现

采购请求:

// 采购请求
public class PurchaseRequest
{
    
    
    public double Amount; // 金额
    public string? ProductName{
    
    get; set;} // 产品名

    public PurchaseRequest(string productName, double amount)
    {
    
    
        ProductName = productName;
        Amount = amount;
    }
}

审批人(抽象类):

// 审批人,handler
public abstract class Approver
{
    
    
    public string? Name{
    
    get; set;}

    private Approver? _nextApprover;

    public Approver(string name)
    {
    
    
        Name = name;
    }

    // 设置下一个审批人
    public Approver SteNextApprover(Approver approver)
    {
    
    
        _nextApprover = approver;
        return approver;
    }

    // 审批
    public virtual void Handle(PurchaseRequest request)
    {
    
    
        if (_nextApprover != null)
            _nextApprover.Handle(request);
        else
            Console.WriteLine("事件链无法处理该请求");
    }
}

具体审批人:

// 经理
public class Manager : Approver
{
    
    
    public Manager(string name) : base(name){
    
    }

    public override void Handle(PurchaseRequest request)
    {
    
    
        if (request.Amount < 10000.0)
            Console.WriteLine($"Manager({
      
      Name})处理了请求采购请求({
      
      request.ProductName}, {
      
      request.Amount})");
        else
            base.Handle(request);
    }
}

// 副总
public class VicePresident : Approver
{
    
    
    public VicePresident(string name) : base(name){
    
    }

    public override void Handle(PurchaseRequest request)
    {
    
    
        if (request.Amount < 25000.0)
            Console.WriteLine($"VicePresident({
      
      Name})处理了请求采购请求({
      
      request.ProductName}, {
      
      request.Amount})");
        else
            base.Handle(request);
    }
}

// 总经理
public class President : Approver
{
    
    
    public President(string name) : base(name){
    
    }

    public override void Handle(PurchaseRequest request)
    {
    
    
        if (request.Amount < 100000.0)
            Console.WriteLine($"President({
      
      Name})处理了请求采购请求({
      
      request.ProductName}, {
      
      request.Amount})");
        else
            base.Handle(request);
    }
}

客户端:

Console.WriteLine("----------------------- 责任链模式 ----------------------------");
PurchaseRequest requestTelphone = new PurchaseRequest("Telphone", 4000.0);
PurchaseRequest requestSoftware = new PurchaseRequest("Visual Studio", 10000.0);
PurchaseRequest requestComputers = new PurchaseRequest("Computers", 40000.0);

Approver manager = new Manager("LearningHard");
Approver Vp = new VicePresident("Tony");
Approver Pre = new President("BossTom");

// 设置责任链
manager.SteNextApprover(Vp).SteNextApprover(Pre);

// 处理请求
manager.Handle(requestTelphone);
manager.Handle(requestSoftware);
manager.Handle(requestComputers);

Vp.Handle(requestSoftware);

Manager(LearningHard)处理了请求采购请求(Telphone, 4000)
VicePresident(Tony)处理了请求采购请求(Visual Studio, 10000)
President(BossTom)处理了请求采购请求(Computers, 40000)
VicePresident(Tony)处理了请求采购请求(Visual Studio, 10000)