• 设计模式——职责链模式


    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。

    适用性:

    •     有多个对象处理一个请求,那个对象处理该请求在运行时刻决定。
    •     你想在不明确接收者的情况下,向多个对象中中的一个提交一个请求
    •     可处理一个对象的请求集合应被动态指定

    参与者:

    Handler:

    ——定义一个处理请求的接口

    ——(可选)实现后继链。

    ConcreteHandler

    ——处理他所负责的请求

    ——如果可处理该请求则处理,如果不行则将该请求转给他的后继者

    Client

    ——向链上的的具体处理者(concreteHandler)对象提交请求

    公司规定,采购架构总价在1万之内,经理级别的人批准即可,总价大于1万小于2万5的则还需要副总进行批准,总价大于2万5小于10万的需要还需要总经理批准,而大于总价大于10万的则需要组织一个会议进行讨论。对于这样一个需求,最直观的方法就是设计一个方法,参数是采购的总价,然后在这个方法内对价格进行调整判断,然后针对不同的条件交给不同级别的人去处理,这样确实可以解决问题,但这样一来,我们就需要多重if-else语句来进行判断,但当加入一个新的条件范围时,我们又不得不去修改原来设计的方法来再添加一个条件判断,这样的设计显然违背了“开-闭”原则。这时候,可以采用责任链模式来解决这样的问题。具体实现代码如下所示。

      1 // 采购请求
      2     public class PurchaseRequest
      3     {
      4         // 金额
      5         public double Amount { get; set; }
      6         // 产品名字
      7         public string ProductName { get; set; }
      8         public PurchaseRequest(double amount, string productName)
      9         {
     10             Amount = amount;
     11             ProductName = productName;
     12         }
     13     }
     14 
     15     // 审批人,Handler
     16     public abstract class Approver
     17     {
     18         public Approver NextApprover { get; set; }
     19         public string Name { get; set; }
     20         public Approver(string name)
     21         {
     22             this.Name = name;
     23         }
     24         public abstract void ProcessRequest(PurchaseRequest request);
     25     }
     26 
     27     // ConcreteHandler
     28     public class Manager : Approver
     29     {
     30         public Manager(string name)
     31             : base(name)
     32         { }
     33 
     34         public override void ProcessRequest(PurchaseRequest request)
     35         {
     36             if (request.Amount < 10000.0)
     37             {
     38                 Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);
     39             }
     40             else if (NextApprover != null)
     41             {
     42                 NextApprover.ProcessRequest(request);
     43             }
     44         }
     45     }
     46 
     47     // ConcreteHandler,副总
     48     public class VicePresident : Approver
     49     {
     50         public VicePresident(string name)
     51             : base(name)
     52         { 
     53         }
     54         public override void ProcessRequest(PurchaseRequest request)
     55         {
     56             if (request.Amount < 25000.0)
     57             {
     58                 Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);
     59             }
     60             else if (NextApprover != null)
     61             {
     62                 NextApprover.ProcessRequest(request);
     63             }
     64         }
     65     }
     66 
     67     // ConcreteHandler,总经理
     68     public class President :Approver
     69     {
     70         public President(string name)
     71             : base(name)
     72         { }
     73         public override void ProcessRequest(PurchaseRequest request)
     74         {
     75             if (request.Amount < 100000.0)
     76             {
     77                 Console.WriteLine("{0}-{1} approved the request of purshing {2}", this, Name, request.ProductName);
     78             }
     79             else
     80             {
     81                 Console.WriteLine("Request需要组织一个会议讨论");
     82             }
     83         }
     84     }
     85 
     86     class Program
     87     {
     88         static void Main(string[] args)
     89         {
     90             PurchaseRequest requestTelphone = new PurchaseRequest(4000.0, "Telphone");
     91             PurchaseRequest requestSoftware = new PurchaseRequest(10000.0, "Visual Studio");
     92             PurchaseRequest requestComputers = new PurchaseRequest(40000.0, "Computers");
     93 
     94             Approver manager = new Manager("LearningHard");
     95             Approver Vp = new VicePresident("Tony");
     96             Approver Pre = new President("BossTom");
     97 
     98             // 设置责任链
     99             manager.NextApprover = Vp;
    100             Vp.NextApprover = Pre;
    101 
    102             // 处理请求
    103             manager.ProcessRequest(requestTelphone);
    104             manager.ProcessRequest(requestSoftware);
    105             manager.ProcessRequest(requestComputers);
    106             Console.ReadLine();
    107         }
    108     }

    既然,原来的设计会因为价格条件范围的变化而导致不利于扩展,根据“封装变化”的原则,此时我们想的自然是能不能把价格范围细化到不同的类中呢?因为每个价格范围都决定某个批准者,这里就联想到创建多个批准类,这样每个类中只需要针对他自己这个范围的价格判断。这样也就是责任链的最后实现方式了。

    学习于    https://www.cnblogs.com/zhili/p/ChainOfResponsibity.html

  • 相关阅读:
    Java byte类型转换成int类型时需要 & 0XFF的原因
    Java 原码 反码 补码
    HTTP 响应头信息(Http Response Header) Content-Length 和 Transfer-Encoding
    [No0000E6]C# 判断与循环
    [No0000E5]C# 运算符
    [No0000E3]C# 数据类型
    [No0000E2]Vmware虚拟机安装 苹果系统 mac OS 10.12
    [No0000E1]C# 关键字
    [No0000E0]批量打开当前路径下的文件
    [No0000DF]C# ZipFileHelper ZIP类型操作,压缩解压 ZIP 类封装
  • 原文地址:https://www.cnblogs.com/cwmizlp/p/9145184.html
Copyright © 2020-2023  润新知