深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
模式动机
职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。
链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,将请求的发送者和请求的处理者解耦。这就是职责链模式的模式动机。
模式定义
职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。由于英文翻译的不同,职责链模式又称为责任链模式,它是一种对象行为型模式。
Chain of Responsibility Pattern: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
Frequency of use: medium low
UML图
模式结构
职责链模式包含如下角色:
Handler: 抽象处理者
ConcreteHandler: 具体处理者
Client: 客户类
模式分析
在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
请求在这条链上传递,直到链上的某一个对象处理此请求为止。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
实例:审批假条
某OA系统需要提供一个假条审批的模块,如果员工请假天数小于3天,主任可以审批该假条;如果员工请假天数大于等于3天,小于10天,经理可以审批;如果员工请假天数大于等于10天,小于30天,总经理可以审批;如果超过30天,总经理也不能审批,提示相应的拒绝信息
模式实例与解析
示例代码—加薪非要老总批?
体系结构
Manager.cs
namespace ChainofResponsibilityPattern
{
//管理者
abstract class Manager
{
protected string name;
//管理者的上级
protected Manager superior;
public Manager(string name)
{
this.name = name;
}
//设置管理者的上级
public void SetSuperior(Manager superior)
{
this.superior = superior;
}
//申请请求
abstract public void RequestApplications(Request request);
}
}
Request.cs
namespace ChainofResponsibilityPattern
{
class Request
{
//申请类别
private string requestType;
public string RequestType
{
get { return requestType; }
set { requestType = value; }
}
//申请内容
private string requestContent;
public string RequestContent
{
get { return requestContent; }
set { requestContent = value; }
}
//数量
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
}
}
CommonManager.cs
using System; namespace ChainofResponsibilityPattern
{
//经理
class CommonManager : Manager
{
public CommonManager(string name)
: base(name)
{
}
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= )
{
//经理所能有的权限就是可批准下属两天内的假期
Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
}
else
{
if (superior != null)
{
superior.RequestApplications(request);//其余的申请都需转到上级
}
}
}
}
}
Majordomo.cs
using System; namespace ChainofResponsibilityPattern
{
//总监
class Majordomo : Manager
{
public Majordomo(string name)
: base(name)
{
}
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假" && request.Number <= )
{
//总监所能有的权限就是可批准下属一周内的假期
Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
}
else
{
if (superior != null)
{
superior.RequestApplications(request);//其余的申请都需转到上级
}
}
}
}
}
GeneralManager.cs
using System; namespace ChainofResponsibilityPattern
{
//总经理
class GeneralManager : Manager
{
public GeneralManager(string name)
: base(name)
{
}
public override void RequestApplications(Request request)
{
if (request.RequestType == "请假")
{
//总经理可准许下属任意天的假期
Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
}
else if (request.RequestType == "加薪" && request.Number <= )
{
Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number);
}
else if (request.RequestType == "加薪" && request.Number > )
{
Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number);
}
}
}
}
Client:客户类
using System; namespace ChainofResponsibilityPattern
{
class Program
{
static void Main(string[] args)
{
CommonManager commonManger = new CommonManager("张经理");
Majordomo majordomo = new Majordomo("李总监");
GeneralManager generalManager = new GeneralManager("王总经理");
//设置上级,完全可以根据实际需求来更改设置
commonManger.SetSuperior(majordomo);
majordomo.SetSuperior(generalManager); Request request = new Request();
request.RequestType = "请假";
request.RequestContent = "小菜请假";
request.Number = ;
//客户端的申请都是由经理发起,但实际谁来决策由具体类来处理,客户端不知道
commonManger.RequestApplications(request); Request request2 = new Request();
request2.RequestType = "请假";
request2.RequestContent = "小菜请假";
request2.Number = ;
commonManger.RequestApplications(request2); Request request3 = new Request();
request3.RequestType = "加薪";
request3.RequestContent = "小菜请求加薪";
request3.Number = ;
commonManger.RequestApplications(request3); Request request4 = new Request();
request4.RequestType = "加薪";
request4.RequestContent = "小菜请求加薪";
request4.Number = ;
commonManger.RequestApplications(request4); Console.Read();
}
}
}
模式优缺点
职责链模式的优点
降低耦合度
可简化对象的相互连接
增强给对象指派职责的灵活性
增加新的请求处理类很方便
职责链模式的缺点
不能保证请求一定被接收。
系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
模式适用环境
在以下情况下可以使用职责链模式:
有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可动态指定一组对象处理请求。
【声明与感谢】
本文,站在许多巨人的肩膀上,借鉴和引用了许多他人拥有版权的作品或著述,在此,对前人们的贡献致谢。并同时公布引用的内容、原作者或来源(一些来源于互联网的内容本人无法追述本源,深表遗憾)。
【参考文献】
《设计模式—可复用面向对象软件的基础》作者: [美] Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 / 刘建中 等 机械工业出版社
《重构—改善既有代码的设计》作者: Martin Fowler译者:候捷 中国电力出版社
《敏捷软件开发—原则、模式与实践》作者: Robert C. Martin 清华大学出版社
《程序员修炼之道—从小工到专家》作者: Andrew Hunt / David Thomas 电子工业出版社
《Head First 设计模式》作者: 弗里曼 译者: O'Reilly Taiwan公司 中国电力出版社
《设计模式之禅》 作者: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计模式纵横谈》 讲师:李建忠
刘伟. 设计模式. 北京:清华大学出版社, 2011.
刘伟. 设计模式实训教程. 北京:清华大学出版社, 2012.
《大话设计模式》 作者: 程杰 清华大学出版社
《C#图解教程》作者: 索利斯 译者: 苏林 / 朱晔 人民邮电出版社
《你必须知道的.NET》作者: 王涛
《项目中的.NET》作者: 李天平 电子工业出版社
《Microsoft .NET企业级应用架构设计》作者: (美)埃斯波西托等编著 译者: 陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客作者:吕震宇
http://www.cnblogs.com/terrylee 博客作者:李会军
http://www.cnblogs.com/anlyren/ 博客作者:anlyren
http://www.cnblogs.com/idior 博客作者:idior
http://www.cnblogs.com/allenlooplee 博客作者:Allen lee
http://blog.csdn.net/ai92 博客作者:ai92
http://www.cnblogs.com/umlonline/ 博客作者:张传波
http://www.cnblogs.com/lovecherry/ 博客作者:LoveCherry
深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)的更多相关文章
- C#设计模式——职责链模式(Chain Of Responsibility Pattern)
一.概述 在软件开发中,某一个对象的请求可能会被多个对象处理,但每次最多只有一个对象处理该请求,对这类问题如果显示指定请求的处理对象,那么势必会造成请求与处理的紧耦合,为了将请求与处理解耦,我们可以使 ...
- 责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)
责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这 ...
- 设计模式:职责链模式(Chain of Responsibility)
去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985.211的娃呢),但是对于某些人来说就是福音了.大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不 ...
- 职责链模式(chain of responsibility Pattern)
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. •Handler: 抽象处理者:定义出一个 ...
- C#设计模式-责任链模式(Chain of Responsibility Pattern)
引子 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现.现在以请假流程为例,一般公 ...
- 23种设计模式--责任链模式-Chain of Responsibility Pattern
一.责任链模式的介绍 责任链模式用简单点的话来说,将责任一步一步传下去,这就是责任,想到这个我们可以相当击鼓传花,这个是为了方便记忆,另外就是我们在项目中经常用到的审批流程等这一类的场景时我们就可以考 ...
- atitit.设计模式(1)--—职责链模式(chain of responsibility)最佳实践O7 日期转换
atitit.设计模式(1)---职责链模式(chain of responsibility)最佳实践O7 日期转换 1. 需求:::日期转换 1 2. 可以选择的模式: 表格模式,责任链模式 1 3 ...
- 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就 ...
- 设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)
设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述 你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决.不能解决就 ...
随机推荐
- javaWeb中servlet开发(4)——servlet跳转
servlet跳转 1.跳转类型 客户端跳转:跳转后地址栏改变,无法传递request范围内属性,是在所有的操作都执行完毕之后才发生跳转的操作,跳转语法是,response.sendRedict() ...
- Android WebView常见问题及解决方案汇总
Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是 ...
- tableView主从表在storyboard连线是 Selcetion Segue和Accessory Action的区别
当按住Ctorl这样连线时会出现,当选择Selection Segue下面的push时,点击cell的任何位置都会跳转到下一个tableView,当选择Accessory Action的下面的push ...
- Inside Flask - flask 扩展加载过程
Inside Flask - flask 扩展加载过程 flask 扩展(插件)通常是以 flask_<扩展名字> 为扩展的 python 包名,而使用时,可用 import flask. ...
- Android-项目介绍
一个.net开发人员 在了解android项目只能凭自己的理解慢慢来了! 新建项目 右击 New-JAVA Application Project 傻瓜似的下一步骤填写每一步 文件介绍 Android ...
- 产生0-9 A-Z a-z
>题目要求: >>产生26个大写字母 >>产生26个小写字母 >>产生0-9这10个阿拉伯数字 >程序实现: package cn.fury.test; ...
- kafka 命令行操作
1.创建主题(topic) bin/kafka-topics.sh --create --zookeeper m6:2181 --replication-factor 1 --partitions 1 ...
- iOS,视图控制器相关(UIViewController)
1.视图控制器各个方法调用时机 2.选项卡(Tab Bar)和导航栏(Navigation Bar) 3.有无控制器的页面跳转 4.页面跳转隐藏底部选项卡 5.获取导航栏和状态栏高度,隐藏导航栏返回按 ...
- 使用复合索引代替单键索引,来避免单键有null值的情况
查看原表: SQL> select count(*) from t1; COUNT(*) ---------- 3229088 SQL> select count(*) from t1 w ...
- Idea 常用快捷键列表
Idea 常用快捷键列表 Alt+回车 导入包,自动修正Ctrl+N 查找类Ctrl+Shift+N 查找文件Ctrl+Alt+L 格式化代码Ctrl+Alt+O 优化导入的类和包Alt+Insert ...