使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
适用性:
- 有多个对象处理一个请求,那个对象处理该请求在运行时刻决定。
- 你想在不明确接收者的情况下,向多个对象中中的一个提交一个请求
- 可处理一个对象的请求集合应被动态指定
参与者:
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