职责链模式---设计模式(19)
2018-06-23 22:28:29来源:未知 阅读 ()
一、定义
职责链模式:使得多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
解释:简单来说应该是对于一个请求,不同的人根据自己职责范围对它进行处理,同时也因为它一般是从底层向上层传递的请求的,所以将处理该请求的不同的对象比喻成一个链,从相对“低”的地方传递到相对“高”的地方,从而完成请求操作。
二、UML类图及基本代码
基本代码:
abstract class Handler { protected Handler successor; public void SetSuccessor(Handler successor) { this.successor = successor; } public abstract void HandleRequest(int request); } class ConcreteHandler1 : Handler { public override void HandleRequest(int request) { if (request >= 0 && request < 10) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } } class ConcreteHandler2 : Handler { public override void HandleRequest(int request) { if (request >= 10 && request < 20) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } } class ConcreteHandler3 : Handler { public override void HandleRequest(int request) { if (request >= 20 && request < 30) { Console.WriteLine("{0}处理请求{1}", this.GetType().Name, request); } else if (successor != null) { successor.HandleRequest(request); } } }
客户端调用及其结果:
Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.SetSuccessor(h2); h2.SetSuccessor(h3); int[] requests = { 6, 5, 14, 23, 18, 9, 17, 6, 26 }; foreach (int request in requests) { h1.HandleRequest(request); }
三、具体实例
列举一个能更加说明职责链的实例。john在单位,向领导请假,小于等于2天经理有权利批准,小于等于5天总监有权利批准,其他的则要交到总经理那里批准。具体代码如下:
class Request { public string RequestType{get;set;} public string RequestContent{get;set;} public int Number{get;set;} } abstract class Manager { protected string name; protected Manager superior; public Manager(string name) { this.name = name; } public void SetSuperior(Manager superior) { this.superior = superior; } public abstract void RequestApplications(Request request); } class CommonManager : Manager { public CommonManager(string name) : base(name) { } public override void RequestApplications(Request request) { if (request.RequestType == "leave" && request.Number <= 2) { Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number); } else { if (superior != null) { superior.RequestApplications(request); } } } } class Majordome : Manager { public Majordome(string name) : base(name) { } public override void RequestApplications(Request request) { if (request.RequestType == "leave" && request.Number <= 5) { Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number); } else { if (superior != null) { superior.RequestApplications(request); } } } } class GeneralManager : Manager { public GeneralManager(string name) : base(name) { } public override void RequestApplications(Request request) { if (request.RequestType == "leave") { Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number); } else if (request.RequestType == "add money" && request.Number <= 500) { Console.WriteLine("{0}:{1} number is {2} ok", name, request.RequestContent, request.Number); } else if (request.RequestType == "add money" && request.Number > 500) { Console.WriteLine("{0}:{1} number is {2} not ok", name, request.RequestContent, request.Number); } } }
客户端调用及结果:
CommonManager jinli = new CommonManager("经理"); Majordome zongjian = new Majordome("总监"); GeneralManager zhongjingli = new GeneralManager("总经理"); jinli.SetSuperior(zongjian); zongjian.SetSuperior(zhongjingli); Request request = new Request(); request.RequestType = "leave"; request.RequestContent = "john ask for days"; request.Number = 2; jinli.RequestApplications(request); Request request2 = new Request(); request2.RequestType = "leave"; request2.RequestContent = "john ask for days"; request2.Number = 5; jinli.RequestApplications(request2);
四、优缺点及适用场景
优点:
1)降低了请求发送者和处理者之间的耦合。
2)把多个条件判定分散到各个处理类中,使得代码更加清晰,责任更加明确。
缺点:
1)在找到正确的处理对象之前,所有的条件判定都要执行一遍,当职责链过长时,可能会引起性能问题。
2)可能导致某个请求不被处理。
适用场景:
1)一个系统的请求需要多个对象进行审批才能完成的情况。
2)代码中有多个if-else时,也可以考虑使用职责链模式对代码进行重构。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:ADO.NET基础02
下一篇:C#文本文件导入数据库
- javascript设计模式 接口介绍 2019-09-23
- vue之手把手教你写日历组件 2019-08-14
- 前端笔记之微信小程序(二){{}}插值和MVVM模式&数 2019-08-14
- JavaScript知识点---->运算规则与运算(逻辑、位) 2019-08-14
- 世界上最大的软件注册表-----npm 2019-08-14
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash