设计模式——职责链模式

 

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

 

适用性:

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

 

参与者:

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

posted on 2018-06-06 15:05  勤学才是王道  阅读(145)  评论(0编辑  收藏  举报

导航