设计模式之责任链模式(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;
}
else
return 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路由(链式)和广播模式(群发)的实现,这下大家就明白了吧;
当然也请注意链式结构的效率问题,对于层级最好还是加以控制。
应用场景
- 基于链式的请求和应答的结构;
- 发送者并不知道在链中的哪个对象会响应请求;
- 责任链中的每一个对象都有职责绝对是否对请求进行响应
设计模式之责任链模式(Chain of Responsibility )的更多相关文章
- 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)
原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of R ...
- 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)
责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...
- 设计模式 笔记 责任链模式 chain of responsibility
//---------------------------15/04/25---------------------------- //Chain of responsibility 责任链----- ...
- [设计模式] 13 责任链模式 Chain of Responsibility
转 http://blog.csdn.net/wuzhekai1985 http://www.jellythink.com/archives/878 向项目经理提交了休假申请,我的项目经理向 ...
- 责任链模式-Chain of Responsibility(Java实现), 例2
责任链模式-Chain of Responsibility 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. 咱们在 ...
- 责任链模式-Chain of Responsibility(Java实现), 例1
责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...
- 《JAVA设计模式》之责任链模式(Chain of Responsibility)
在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...
- 责任链模式/chain of responsibility/行为型模式
职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...
- 设计模式之二十:责任链模式(Chain of Responsibility)
感觉这个设计模式和组合模式一样是一种非常巧妙的设计模式,在须要使用它的地方假设不使用这样的设计模式代码会变的非常复杂,可是这样的设计模式的基本原理又是非常easy的. 责任链模式: 通过使多个对象都有 ...
- C#设计模式-责任链模式(Chain of Responsibility Pattern)
引子 一个事件需要经过多个对象处理是一个挺常见的场景,譬如采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程,可以考虑使用责任链模式来实现.现在以请假流程为例,一般公 ...
随机推荐
- 桌面应用开发之WPF页面导航
先看效果图 Get Start 为了项目解耦,使用mvvmlight框架.MVVM设计模式请自行了解. 1 新建项目 新建一个MvvmLight(WPF)项目,删除其中无关文件夹:Design ...
- 【WPF】【UWP】借鉴 asp.net core 管道处理模型打造图片缓存控件 ImageEx
在 Web 开发中,img 标签用来呈现图片,而且一般来说,浏览器是会对这些图片进行缓存的. 比如访问百度,我们可以发现,图片.脚本这种都是从缓存(内存缓存/磁盘缓存)中加载的,而不是再去访问一次百度 ...
- 腾讯Alloy团队代码规范
概述 我个人很看重代码规范,因为代码是写给别人看的,按规范写别人才更容易理解.之前苦于没有代码规范的资料,现在在github上面看到了腾讯Alloy团队的代码规范,于是学习了一下,并记录下我自己还没怎 ...
- EXCEL在改动某几个单元格时隐藏空列
概述 今天我哥来找我帮他搞下excel表格,本着程序猿对程序无所不能的精神,我爽快的答应了.结果查了半天才搞定.现在记录在此,供自己以后参考,相信对其他人也有用. PS:这几天正在弄博客,马上就要弄完 ...
- Zabbix-2--安装--LAMP/LNMP详细总结
- Shell-6--预定义变量
- interface中定义default方法和static方法
interface的default方法和static方法 接口中可以定义static方法,可通过接口名称.方法名()调用,实现类不能继承static方法: 接口中可以定义default方法,defau ...
- 07-部署Flanneld网络
部署Flanneld网络 Flanneld:用于解决容器之间网络互通,这里我们要配置TLS认证. Docker1.12.5:docker的安装很简单,这里也不说了. 配置Flanneld 这里我们使用 ...
- spring boot -thymeleaf-逻辑控制
th:if th:switch
- spring boot -thymeleaf-日期转化
<span th:text="${#dates.format(date)}" ></span><span th:text="${#dates ...