C#设计模式之责任链模式

责任链模式


本篇博客将介绍责任链模式,责任链模式是行为型设计模式,行为型模式关注对象之间的交互,研究系统在运行时对象之间的相互通讯和协作,进一步明确对象的职责。当我们的系统中存在多个对象可以处理同一个请求的时候,我们就可以通过责任链模式将这些处理请求的对象连成一条链,让请求可以沿着这个链传播。如果链上的对象可以处理该请求就处理,否则就转发给下家。

模式分类

行为型设计模式。

模式产生的原因

在很多情况下,可以处理对象请求的对象不止一个,例如大学里的奖学金审批,学生再向辅导员提交申请表后,首先是辅导员签字审批,然后交给系主任签字审批,接着是院长,最后是校长。在这个过程中,学生的申请表可以看作是一个请求对象,而辅导员,系主任,院长,校长就是一个一个的责任链对象,除了辅导员外学生不需要与其他的审批者一一交互。

实际上责任链可以是一条直线,一个环或者一个树形结构。最常见的责任链就是直线型,也就是沿着一条单向的链来传递请求。链上的每一个对象都是请求的处理者,职责链模式可以将对象处理者连成一条线,并让请求沿着链传播,客户端只需要将请求放在链上即可,将请求的发送者和处理者解耦,这就是责任链模式的动机。

模式类图

在这里插入图片描述

由图可知,责任链模式由2个对象构成:

Handler():

它定义一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不一样,因此在其中定义一个抽象的处理方法。同时该类需要维持一个指向下家的引用,通过该引用,处理者可以连成一条线。

ConcreteHandler():

他是抽象处理者的子类,负责实现抽象处理者中的抽象处理方法,在处理方法中具体处理者应该书写处理请求的方法和如果不满足特定条件就发往下家。

代码实现

例子:某企业而得SCM系统中包含一个采购审批子系统。该企业的采购审批时分批进行的,即根据采购金额的不同由不同层级的主管人员来审批,主任可以审批5万元以下的采购单,董事长可以审批5万元到10万元的采购单,100万元以上需要开会决定,请使用责任链模式模拟该系统。

Approver审批人基类:

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public abstract class Approver
    {
    
    
        protected Approver NextApprover;
        protected string Name;

        public Approver(string name)
        {
    
    
            Name = name;
        }
        public void SetApprover(Approver nextApprover)
        {
    
    
            NextApprover = nextApprover;
        }

        public abstract void Operation(PurchaseArgs args);
    }
}

PurchaseArgs采购信息类:

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public class PurchaseArgs
    {
    
    
        public float TotalMoney;
        public string ObjectName;
    }
}

Director采购员类:

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public class Director : Approver
    {
    
    
        
        public override void Operation(PurchaseArgs args)
        {
    
    
            NextApprover.Operation(args);
        }

        public Director(string name) : base(name)
        {
    
    
        }
    }
}

VicePresident主任类:

using System;
using System.Diagnostics;

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public class VicePresident : Approver
    {
    
    
        
        public override void Operation(PurchaseArgs args)
        {
    
    
            if (args.TotalMoney < 50000f)
            {
    
    
                Console.WriteLine($"{
      
      Name}处理了该条订单{
      
      args.ObjectName},金额为{
      
      args.TotalMoney}");
            }
            else
            {
    
    
                NextApprover.Operation(args);
            }
        }

        public VicePresident(string name) : base(name)
        {
    
    
        }
    }
}

President董事长类:

using System;

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public class President : Approver
    {
    
    
        

        public override void Operation(PurchaseArgs args)
        {
    
    
            if (args.TotalMoney < 100000f)
            {
    
    
                Console.WriteLine($"{
      
      Name}处理了该条订单{
      
      args.ObjectName},金额为{
      
      args.TotalMoney}");
            }
            else
            {
    
    
                NextApprover.Operation(args);
            }
        }

        public President(string name) : base(name)
        {
    
    
        }
    }
}

Congress开会决议类:

using System;

namespace ChainOfResponsibility.ChainOfResponsibility.Example
{
    
    
    public class Congress : Approver
    {
    
    

        public override void Operation(PurchaseArgs args)
        {
    
    
            if (args.TotalMoney < 1000000f)
            {
    
    
                Console.WriteLine($"{
      
      Name}处理了该条订单{
      
      args.ObjectName},金额为{
      
      args.TotalMoney}");
            }
            else
            {
    
    
                Console.WriteLine($"订单废弃");
            }
        }

        public Congress(string name) : base(name)
        {
    
    
        }
    }
}

Program类:

using ChainOfResponsibility.ChainOfResponsibility.Example;
using ChainOfResponsibility.ChainOfResponsibility.Question4;
using Director = ChainOfResponsibility.ChainOfResponsibility.Question4.Director;

namespace ChainOfResponsibility
{
    
    
    internal class Program
    {
    
    
        public static void Main(string[] args)
        {
    
    
           Director director = new Director("director");
            VicePresident vicePresident = new VicePresident("vicePresident");
            President president = new President("president");
            Congress congress = new Congress("congress");
            director.SetApprover(vicePresident);
            vicePresident.SetApprover(president);
            president.SetApprover(congress);
            director.Operation(new PurchaseArgs()
            {
    
    
                ObjectName = "玩具",
                TotalMoney = 1000,
            });
            director.Operation(new PurchaseArgs()
            {
    
    
                ObjectName = "桌子",
                TotalMoney = 20000,
            });
            director.Operation(new PurchaseArgs()
            {
    
    
                ObjectName = "电视",
                TotalMoney = 500000,
            });
            director.Operation(new PurchaseArgs()
            {
    
    
                ObjectName = "工厂",
                TotalMoney = 9000000,
            });
        }
    }
}

责任链模式总结

责任链模式的优点:

  1. 责任链模式使得一个对象无需知道是其他那一个对象处理其请求,仅需知道该请求会被处理即可。请求者和接收者之间解耦。更形象一点,责任链模式是一种情况下对于ifelse这种条件分支的解耦。,
  2. 再给对象分配职责时,责任链模式可以带来更多的灵活性,可以在运行时对该链进行动态的增加和修改。符合开闭原则。

责任链模式的缺点:

  1. 由于一个请求并没有直接指定的处理者,所以存在请求最终不能被处理的风险。
  2. 对于较长的责任链,系统性能会受到影响。
  3. 如果键链不当可能会导致循环调用。

猜你喜欢

转载自blog.csdn.net/BraveRunTo/article/details/118805271
今日推荐