设计模式之责任链模式(Chain of Responsibility )
责任链的目的是通过特定的设计对请求者和接收者之间进行解耦,请求者调用操作的对象,接收者接收请求并执行相关操作,通过解耦请求者不需要关心接收者的接口,同时也可增强职责的灵活性,通过改变链内的成员或调用次序,允许动态新增或删除责任。
作用
责任链模式通过将多个对象连成链式模式,并沿着这个链传递命令或者请求,直到有对象处理它为止。
类视图
实现
我们还是取比较经典的员工请假的例子。员工为请假的请求者,接收者分别从项目经理、部门经理、公司经理这几个层级,员工向上进行请假操作,首先传递给项目经理,项目经理在处理时分为两种情况,如果项目经理人在公司,并且员工的请假天数满足请假的审批权限范围,则给予审批,反之则申请上级进行处理。
当然我们也可以制定自己的特殊规则,比如经理级别的接收者如果人不在,就不能向上进行请求,比如开可以增加请假的事由以供经理进行判断是否满足请假要求等,这些都可以根据实际情况进行扩充,感兴趣可以自己实现。
class DayOffRequest
{
public: DayOffRequest(int hour) :m_iHour(hour) {} int GetHour() { return m_iHour; }
private: int m_iHour;
}; class Manager
{
public: virtual bool HandleRequest(DayOffRequest* request) = 0;
}; class PM : public Manager //Project manager项目经理
{
public: PM(Manager* handler) :m_Handler(handler) {} bool HandleRequest(DayOffRequest* request) { //在权责范围内给予批准if (request->GetHour() <= 2) { cout << "PM said : OK" << endl; return true; }else if (m_Handler) //请求上级{return m_Handler->HandleRequest(request);}else{//无法定夺cout <<"PM said :no decide" << endl; return false;}}
private: Manager* m_Handler;
}; class DM : public Manager //Department Manager部门经理
{
public: DM(Manager* handler) :m_handler(handler) {} bool HandleRequest(DayOffRequest* request) { if (m_Handler){if(request->getHour() <=16){cout <<"DM said :OK" << endl; return true;}elsereturn m_Handler->HandleRequest(request);}else{ cout <<"DM said :no decide" << endl; return false;}}
private: Manager *m_handler;
}; class GM : public Manager //General Manager 总经理
{
public: GM():m_handler(NULL) {}bool IsInCompany(){return static_cast<bool>(rand()%2) ;}bool HandleRequest(DayOffRequest* request) { if(IsInCompany()){cout <<"GM said :OK" << endl; return true;}else{cout <<"GM said :try again latter" << endl; return false;}}
private: Manager* m_handler;
};
int main()
{ Manager *general = new GM(); Manager *department = new DM(general); //设置上级 Manager *project = new PM(department); //设置上级 DayOffRequest reqsta(2); //一个员工请假2小时project->DealWithRequest(&reqsta); DayOffRequest reqstb(20); //另一个员工请假20小时project->DealWithRequest(&reqstb); delete project; delete department; delete general;
}
责任链和观察者模式比较相像,都是进行命令和数据的传递,二者的关键区别是一个是有明确层级和先后关系(也可能不是那么明显),而一个是对象平等的,最通俗的例子就是网络中的DNS路由(链式)和广播模式(群发)的实现,这下大家就明白了吧;
当然也请注意链式结构的效率问题,对于层级最好还是加以控制。
应用场景
- 基于链式的请求和应答的结构;
- 发送者并不知道在链中的哪个对象会响应请求;
- 责任链中的每一个对象都有职责绝对是否对请求进行响应
转载于:https://www.cnblogs.com/chencarl/p/8762521.html
设计模式之责任链模式(Chain of Responsibility )相关推荐
- 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)
原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍 为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求, ...
- 责任链模式(Chain of Responsibility)
责任链模式(Chain of Responsibility) 1.意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个 ...
- 责任链模式 Chain of Responsibility
责任链模式是一种设计模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最 ...
- [设计模式-行为型]责任链模式(Chain of Responsibility)
概括 名称 Chain of Responsibility 结构 动机 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一 ...
- java 事件链_Java设计模式——责任链模式(Chain of Responsibility)
责任链 责任链模式通俗来说就是关联一串能够处理事务的对象,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. ...
- 设计模式之职责链模式(Chain of Responsibility)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 十八、责任链模式 ( Chain of Responsibility)
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链 责任链模式给予请求的类型,对请求的发送者和接收者进行解耦 责任链模式中通常每个接收者都包含对 ...
- 『设计模式』职责链模式(Chain of Responsibility) 可怜的加薪、请假之路
23种设计模式+额外常用设计模式汇总 (持续更新) 问题抽象 客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的. 对于客户端而言,无所谓谁来处理,反正有对象处理就 ...
- 设计模式(24)-----责任链模式
责任链模式(chain of responsibility) 定义 责任链模式是对象的行为模式.使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系.将这些对象连成一条链,沿着这条链 ...
最新文章
- 子元素是字典列表转成字典
- Python中@staticmethod和@classmethod之间的区别
- 如何在IIS上配置多个网站,及网站发布配置讲解
- 算法题存档20190206
- configure 查看默认安装路径
- 微软发表IE浏览器 F1漏洞安全公告
- jq将php时间戳转化日期格式,JQuery将时间戳转换为时间
- 记录一下Mac浏览器劫持searchbaron.com的经历
- word自动生成目录如何设置第一页和页码不齐问题
- 利用R语言ggplot2包制作金字塔图,展示人口结构数据
- python 知乎 合并 pdf_怎么把多个pdf合并在一起?
- 北航计算机组成实验课,北航计算机组成实验Project4
- 《Android 应用案例开发大全(第二版)》——1.5节第一个Android程序——Hello Android...
- 【每天听见吴晓波-2016-07-04】上海房价未来五年还会翻番
- 谷歌浏览器按F12调试js代码的时候找不到代码在哪
- 编程基本功训练:流程图画法及练习
- python发短信 金山_Python爬虫基础练习(四) 金山翻译爬取(进阶篇)
- 如何提高节点下线速度或避免因节点掉线产生网络风暴?
- java计算机毕业设计微服务”架构下新闻头条的设计与实现源码+系统+数据库+lw文档
- 20191021 设计图都不会画,还想做”架构师“?
热门文章
- update mysql.user set password_使用update命令来修改Mysql的root密码
- oracle自增列问题i,Oracle序列 和 SQL SERVER 自增列的问题-oracle
- python save保存图片到本地_python爬取网站上的图片并保存到本地
- c语言运行程序没有,这个程序怎么运行?为什么显示没有exe??
- 社区发现(六)--模块度
- linux dd 非常慢,macOS Sierra:dd到USB非常慢,似乎无法使用/ dev / rdisk
- “21天好习惯“第一期-2
- 【数据库原理实验(openGauss)】金融场景化实验
- Azkaban入门简介
- scala练习:依据输入的年和月打印该月日历