设计模式(二十)职责链模式
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
优点:
当客户提交一个请求时,请求是沿链传递直至有一个 ConcreteHandler 对象负责处理它。这就使得接收者和发送者都没有对方的明确消息,且链中的对象自己也不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继的引用,而不 需要保持它所有的候选接收者的引用。这就大大降低了耦合度。

基本代码
1 // Handler 类,定义一个出来请示的接口 2 abstract class Handler 3 { 4 protected Handler successor; 5 6 // 设置继任者 7 public void SetSuccessor(Handler successor) 8 { 9 this.successor = successor; 10 } 11 12 // 处理请求的抽象方法 13 public abstract void HandleRequest(int request); 14 } 15 16 // 具体处理类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者 17 // ConcreteHandler1,当请求数在 0 到 10 之间则有权处理,否则转到下一位 18 class ConcreteHandler1 : Handler 19 { 20 public override void HandleRequest(int request) 21 { 22 if(request >= 0 && request < 10) 23 { 24 Console.WriteLine("{0} 处理请求{ 1} ", this.GetType().Name, request); 25 } 26 else if(successor != null) 27 { 28 // 转移到下一位 29 successor.HandleRequest(request); 30 } 31 } 32 } 33 34 // ConcreteHandler2,当请求数在 10 到 20 之间则有权处理,否则转到下一位 35 class ConcreteHandler2 : Handler 36 { 37 public override void HandleRequest(int request) 38 { 39 if(request >= 10 && request < 20) 40 { 41 Console.WriteLine("{0} 处理请求{ 1} ", this.GetType().Name, request); 42 } 43 else if(successor != null) 44 { 45 // 转移到下一位 46 successor.HandleRequest(request); 47 } 48 } 49 } 50 51 // ConcreteHandler3,当请求数在 20 到 30 之间则有权处理,否则转到下一位 52 class ConcreteHandler3 : Handler 53 { 54 public override void HandleRequest(int request) 55 { 56 if(request >= 20 && request < 30) 57 { 58 Console.WriteLine("{0} 处理请求{ 1} ", this.GetType().Name, request); 59 } 60 else if(successor != null) 61 { 62 // 转移到下一位 63 successor.HandleRequest(request); 64 } 65 } 66 } 67 68 // 客户端,向链上的具体处理者对象提交请求 69 static void Main(string[] args) 70 { 71 // 设置职责链上家与下家 72 Handler h1 = new ConcreteHandler1(); 73 Handler h2 = new ConcreteHandler2(); 74 Handler h3 = new ConcreteHandler3(); 75 h1.SetSuccessor(h2); 76 h2.SetSuccessor(h3); 77 78 int[] requests = {2, 5, 14, 22, 18, 3, 27, 20}; 79 80 // 循环给最小处理者提交请求,不同的数额,由不同权限处理者处理 81 foreach(int request in requests) 82 { 83 h1.HandRequest(request); 84 } 85 86 Console.Read(); 87 }
【例】加薪请求

基本代码
1 // 管理者 2 abstract class Manager 3 { 4 protected string name; 5 // 管理者的上级 6 protected Manager superior; 7 8 public Manager(string name) 9 { 10 this.name = name; 11 } 12 13 // 设置管理者的上级 14 public void SetSuperior(Manager superior) 15 { 16 this.superior = superior; 17 } 18 19 // 申请请求 20 abstract public void RequestApplications(Request request); 21 } 22 23 // 经理 24 class CommonManager : Manager 25 { 26 public CommonManager(string name) : base(name) 27 { 28 } 29 30 public override void RequestApplications(Request request) 31 { 32 if(request.RequestType == "请假" && request.Number <= 2) 33 { 34 Console.WriteLine(“{0} : {1} 数量{2} 被批准”, name, request.RequestContent, request.Number); 35 }else 36 { 37 // 其余的申请都需转到上级 38 if(superior != null) superior.RequestApplications(request); 39 } 40 } 41 } 42 43 // 总监 44 class Majordomo : Manager 45 { 46 public Majordomo(string name) : base(name) 47 { 48 } 49 50 public override void RequestApplications(Request request) 51 { 52 if(request.RequestType == "请假" && request.Number <= 5) 53 { 54 Console.WriteLine(“{0} : {1} 数量{2} 被批准”, name, request.RequestContent, request.Number); 55 }else 56 { 57 // 其余的申请都需转到上级 58 if(superior != null) superior.RequestApplications(request); 59 } 60 } 61 } 62 63 // 总经理(处理全部) 64 class GeneralManager : Manager 65 { 66 public GeneralManager(string name) : base(name) 67 { 68 } 69 70 public override void RequestApplications(Request request) 71 { 72 if(request.RequestType == "请假" ) 73 { 74 Console.WriteLine(“{0} : {1} 数量{2} 被批准”, name, request.RequestContent, request.Number); 75 } 76 else if(request.RequestType == "加薪") 77 { 78 Console.WriteLine(“{0} : {1} 数量{2} 被批准”, name, request.RequestContent, request.Number); 79 } 80 } 81 } 82 83 // 客户端 84 static void Main(string[] args) 85 { 86 CommonManager jinli = new CommonManager("经理"); 87 Majordomo zongjian = new Majordomo("总监"); 88 GeneralManager zongjingli = new GeneralManager("总经理"); 89 90 // 设置上级 91 jinli.SetSuperior(zongjian); 92 zongjian.SetSuperior(zhongjingli); 93 94 Request request = new Request(); 95 request.RequestType = "请假"; 96 request.RequestContent = "小蔡请假"; 97 request.Number = 1; 98 jinli.RequestApplications(request); 99 100 Request request1 = new Request(); 101 request.RequestType = "加薪"; 102 request.RequestContent = "小蔡加薪"; 103 request.Number = 1000; 104 jinli.RequestApplications(request1); 105 106 Console.Read(); 107 }

浙公网安备 33010602011771号