职责链模式(23)
来源:互联网 发布:撤销中国根域名服务器 编辑:程序博客网 时间:2024/06/05 05:18
今天我们来讲一下职责链模式。首先我们来模拟一下下面这个场景。
一、案例
在公司,我们需要向领导请假,向领导申请加薪,不同级别的领导会做出相应的批示。下面我们用简单的控制台应用程序来模拟一下这个案例。
1 /// <summary> 2 /// 申请类 3 /// </summary> 4 class Request 5 { 6 //申请类别 7 private string requestType; 8 public string RequestType 9 { 10 get 11 { 12 return requestType; 13 } 14 15 set 16 { 17 requestType = value; 18 } 19 } 20 //申请内容 21 private string requestContent; 22 public string RequestContent 23 { 24 get 25 { 26 return requestContent; 27 } 28 29 set 30 { 31 requestContent = value; 32 } 33 } 34 //数量 35 private int number; 36 public int Number 37 { 38 get 39 { 40 return number; 41 } 42 43 set 44 { 45 number = value; 46 } 47 } 48 } 49 50 /// <summary> 51 /// 管理者类 52 /// </summary> 53 class Manager 54 { 55 protected string name; 56 57 public Manager(string name) 58 { 59 this.name = name; 60 } 61 //得到结果 62 public void GetResult(string managerLevel, Request request) 63 { 64 //比较长的方法,多条的分支,这些其实都是代码坏味道 65 if (managerLevel == "经理") 66 { 67 if (request.RequestType == "请假" && request.Number <= 2) 68 { 69 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 被批准"); 70 } 71 else 72 { 73 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 我无权处理"); 74 } 75 } 76 else if (managerLevel == "总监") 77 { 78 if (request.RequestType == "请假" && request.Number <= 5) 79 { 80 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 被批准"); 81 } 82 else 83 { 84 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 我无权处理"); 85 } 86 } 87 else if (managerLevel=="总经理") 88 { 89 if (request.RequestType=="请假") 90 { 91 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 被批准"); 92 } 93 else if (request.RequestType=="加薪"&&request.Number<=500) 94 { 95 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 被批准"); 96 } 97 else if (request.RequestType == "加薪" && request.Number > 500) 98 { 99 Console.WriteLine($"{name}:{request.RequestContent} 数量{request.Number} 再说吧");100 }101 }102 }103 }
客户端调用:
1 public static void Main() 2 { 3 //三个管理者 4 Manager jinli = new Manager("金立"); 5 Manager zongjian = new Manager("宗剑"); 6 Manager zhongjingli = new Manager("钟精励"); 7 8 //小魔王请求加薪1000 9 Request request = new Request();10 request.RequestType = "加薪";11 request.RequestContent = "小魔王请求加薪";12 request.Number = 1000;13 14 //不同级别对此请求做判断和处理15 jinli.GetResult("经理", request);16 zongjian.GetResult("总监", request);17 zhongjingli.GetResult("总经理", request);18 19 //请假3天20 Request request2 = new Request();21 request2.RequestType = "请假";22 request2.RequestContent = "小魔王请假";23 request2.Number = 3;24 25 // 不同级别对此请求做判断和处理26 jinli.GetResult("经理", request2);27 zongjian.GetResult("总监", request2);28 zhongjingli.GetResult("总经理", request2);29 30 Console.ReadKey();31 }
好,下面我们来分析一下上述代码,看看有什么问题和缺陷。
①:GetResult这个方法太长,分支太多,让人感觉很不舒服,代码坏了味道。违背了单一职责的原则
②:如果还有其他的管理级别的管理者,那么,就需要修改Manager类,违背了开放-封闭原则。
我们如何才能不仅实现功能,而且还能解决上述的问题呢?下面就是我们要讲的职责链模式了。
什么是职责链模式呢?职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
我们来看一下它的代码结构
1 //定义一个处理请示的接口 2 abstract class Handler 3 { 4 protected Handler successor; 5 //设置继任者 6 public void SetSuccessor(Handler successor) 7 { 8 this.successor = successor; 9 }10 //处理请求的抽象方法11 public abstract void HandleRequest(int request);12 }13 14 //具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理请求就处理它,15 //否则,将该请求转发给它的后继者。16 class ConcreteHandler1 : Handler17 {18 public override void HandleRequest(int request)19 {20 if (request >= 0 && request < 10)21 {22 Console.WriteLine($"{this.GetType().Name}{request}");23 }24 else if (successor != null)25 {26 //转移到下一位去处理27 successor.HandleRequest(request);28 }29 }30 }31 class ConcreteHandler2 : Handler32 {33 public override void HandleRequest(int request)34 {35 if (request >= 10)36 {37 Console.WriteLine($"{this.GetType().Name}{request}");38 }39 else if (successor != null)40 {41 //转移到下一位去处理42 successor.HandleRequest(request);43 }44 }45 }
客户端
1 public static void Main() 2 { 3 Handler h1 = new ConcreteHandler1(); 4 Handler h2 = new ConcreteHandler2(); 5 h1.SetSuccessor(h2); 6 7 int[] requests = {2, 5, 14, 22}; 8 foreach (int request in requests) 9 {10 h1.HandleRequest(request);11 }12 Console.ReadKey();13 }
这当中,最关键的是当客户提交一个请求时,请求是沿着链传递直至有一个ConcreteHandler对象负责处理它。接收者和发送者都没有对方的明确消息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,他们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受着的引用。
下面,我们用职责链模式将我们案例重构一下。
1 /// <summary> 2 /// 申请类 3 /// </summary> 4 class Request 5 { 6 //申请类别 7 private string requestType; 8 public string RequestType 9 { 10 get 11 { 12 return requestType; 13 } 14 15 set 16 { 17 requestType = value; 18 } 19 } 20 //申请内容 21 private string requestContent; 22 public string RequestContent 23 { 24 get 25 { 26 return requestContent; 27 } 28 29 set 30 { 31 requestContent = value; 32 } 33 } 34 //数量 35 private int number; 36 public int Number 37 { 38 get 39 { 40 return number; 41 } 42 43 set 44 { 45 number = value; 46 } 47 } 48 } 49 //管理者 50 abstract class Manager 51 { 52 protected string name; 53 //管理者的上级 54 protected Manager superior; 55 56 public Manager(string name) 57 { 58 this.name = name; 59 } 60 //设置管理者的上级 61 public void SetSuperior(Manager superior) 62 { 63 this.superior = superior; 64 } 65 66 abstract public void RequestApplications(Request request); 67 } 68 //经理 69 class CommonManager:Manager 70 { 71 public CommonManager(string name) : base(name) 72 { 73 } 74 75 public override void RequestApplications(Request request) 76 { 77 if (request.RequestType == "请假" && request.Number <= 2) 78 { 79 Console.WriteLine($"{name}{request.RequestContent}{request.Number}"); 80 } 81 else 82 { 83 //其余的申请都需转到上级 84 if (superior!=null) 85 { 86 superior.RequestApplications(request); 87 } 88 } 89 } 90 } 91 //总监 92 class Majordomo : Manager 93 { 94 public Majordomo(string name) : base(name) 95 { 96 } 97 98 public override void RequestApplications(Request request) 99 {100 if (request.RequestType == "请假" && request.Number <= 5)101 {102 Console.WriteLine($"{name}{request.RequestContent}{request.Number}");103 }104 else105 {106 //其余的申请都需转到上级107 if (superior != null)108 {109 superior.RequestApplications(request);110 }111 }112 }113 }114 //总经理115 class GeneralManager : Manager116 {117 public GeneralManager(string name) : base(name)118 {119 }120 121 public override void RequestApplications(Request request)122 {123 if (request.RequestType == "请假" )124 {125 Console.WriteLine($"{name}{request.RequestContent}{request.Number}");126 }127 else if (request.RequestType=="加薪"&&request.Number<=500)128 {129 Console.WriteLine("批准");130 }131 else132 {133 Console.WriteLine("再说吧");134 }135 }136 }
客户端:
1 public static void Main() 2 { 3 CommonManager jinli = new CommonManager("金立"); 4 Majordomo zongjian = new Majordomo("宗剑"); 5 GeneralManager zhongjingli = new GeneralManager("钟精励"); 6 //根据实际需求设置上级 7 jinli.SetSuperior(zongjian); 8 zongjian.SetSuperior(zhongjingli); 9 10 //客户端的申请都是由‘经理’发起,但实际上谁来决策由具体的管理类来处理,客户端不知道。11 Request request = new Request();12 request.RequestType = "请假";13 request.RequestContent = "小魔王请假";14 request.Number = 1;15 jinli.RequestApplications(request);16 17 Request request2 = new Request();18 request2.RequestType = "请假";19 request2.RequestContent = "小魔王请假";20 request2.Number = 4;21 jinli.RequestApplications(request2);22 23 Request request3 = new Request();24 request2.RequestType = "加薪";25 request2.RequestContent = "小魔王加薪";26 request2.Number = 1000;27 jinli.RequestApplications(request2);28 29 Console.ReadKey();30 }
好了,职责链模式就讲到这里了,下一篇我们讲 中介者模式
本系列将持续更新,喜欢的小伙伴可以点一下关注和推荐,谢谢大家的支持
0 0
- 职责链模式(23)
- 职责链模式(23)
- 职责链模式(23)
- 职责链模式(23)
- 职责链模式(二):职责链模式概述
- 职责链模式(ChainOfResponsibity)
- 职责链模式(变种)
- 职责链模式(python)
- 职责链模式(C++)
- 职责链模式(四):纯与不纯的职责链模式,职责链模式总结
- 责任链模式(职责链模式)
- 设计模式(13)--职责链模式
- 职责链模式(Chain of Responsibility)
- 主题:请假 加薪(职责链模式)
- Chain of Responsibility(职责链模式)
- 职责链(Chain of Responsibility)模式
- 职责链模式(Chain Of Responsibility)
- 职责链模式(Chain of Responsibility)
- bootstrap排版、
- Android 系统的架构
- 使用MySQL命令行新建用户并授予权限
- 关于Growth Hacker的笔记
- JS基础知识补充和性能优化知识学习(CHROME小技巧)
- 职责链模式(23)
- Spark MLlib系列(二):基于协同过滤的电影推荐系统
- java源码解读之Integer
- 文本,块的位置
- Fibonacci数列以及蓝桥杯Fibonacci数列%10007
- 【PAT】1072. Gas Station
- android中跨进程通讯的4种方式
- Spring配置EL表达式
- Perf -- Linux下的系统性能调优工具,第 1 部分