职责链模式将对象的请求处理组成链式结构,并将请求按链式结构逐个传递下去,直接被其中的某个处理者处理为止。由此可知,职责链模式的适用场合是对指定请求,可以有多个请求处理者(或称为请求响应者),但用户并不知道(也不需要知道--------此如做到请求者与响应者的解耦合)当时运行环境下该请求会被具体的哪个处理者处理(又或者说完全都没有被响应)。请求者只是抛出一个请求,响应链内部(即:模式内部)自己决定是否能处理以及谁能处理该请求。该模式的类结构图参考如下:

模式的编码结构参考如下:

 namespace chain_of_responsibility
{
class IHandler
{
public:
IHandler(IHandler* pNextHandler) : m_pNextHandler(pNextHandler) {}
virtual ~IHandler() {}
virtual bool handleRequest(/*requester type parameters here........*/) { /*do something here........*/return false; } private:
IHandler* m_pNextHandler; };//class IHandler class ConcreteHandler1 : public IHandler
{
public:
// some code here........
virtual bool handleRequest(/*requester type parameters here........*/) {
/*
if (can handle this request) {
do something here........
return true;
} else if (nullptr != m_pNextHandler) {
return m_pNextHandler->handleRequest(the parameters........);
}
*/
return false;
} };//class ConcreteHandler1 class ConcreteHandler2 : public IHandler
{
public:
// some code here........
virtual bool handleRequest(/*requester type parameters here........*/) {
/*
if (can handle this request) {
do something here........
return true;
} else if (nullptr != m_pNextHandler) {
return m_pNextHandler->handleRequest(the parameters........);
}
*/
return false;
} };//class ConcreteHandler2 class IRequester {}; class Client
{
public:
void test() {
//
// they are test code below.
//
auto pRequester = new (std::nothrow) IRequester();
auto pHandler1 = new (std::nothrow) ConcreteHandler1(nullptr);
auto pHandler2 = new (std::nothrow) ConcreteHandler2(pHandler1);
pHandler1->handleRequest(pRequester);
} };//class Client }//namespace chain_of_responsibility

职责链模式编码结构参考

职责链主要适合于对某个问题有多种解方式,并且是要在具体的环境下才能具体确定解方式。只是在设计层面上,将所有解方式链成一条链的形式,从链头到链尾逐个传递下去直到问题被某中的某个(当然也有可能都没有)解给处理掉,然后终止。即:只要有解,则解完成后传递终止,否则直至链尾。

职责链模式的好处是,将请求与请求的处理解耦合掉,使得客户不需要依赖于所有解对象,也不需要关心最终请求是被哪个解给处理,客户只关心结果。但是职责链模式在设计上,一定要注意:有些问题的解是要按具体到一般化方向链接的,否则就会出现逻辑上的问题。举例:旅游经费审批问题。

1) 当旅游经费开支 <= 1000RMB时,只需要团队的项目经理审批即可;

2) 当旅游经费开支 > 1000RMB 并且 <= 2000RMB时,需要部门主管审批才可;

3) 当旅游经费 > 2000RMB 并且 <= 3000RMB时,需要区域经理审批才可;

4) 当旅游经费高于 3000RMB时,则需要集团总裁审批。

从以上审批权限来看,项目经理的权限最低,而越往上,职位地高审批的经费额度越大。因此,假如现在开支是2345RMB,则明显的需要区域经理或更高级别的(集团总栽)审批才可以。此时问题就来了,那现在是要让集团总裁审批还是要让区域经理审批了?因为区域经理对具体的业务肯定会比集团总裁更了解,他也肯定更加清楚这笔经费的消费具体细节,理论上,是要区域经理批就可以了。而集团总栽他更注重的应该是集团公司的更大层面的问题,而不应该是这些小问题上,要不集团总栽就没有必要把审批权限开给区域经理了。所以,理论上,该笔消费应该要让区域经理来审批,只有数额大到区域经理审批不了(权限不足)时,才需要进一步上报给集团总栽,由总栽来审批。

另外,如果问题的解有非常多的情况下,其实也会给程序在调试上带来一定的影响。往往需要将所有解都要设置断点(即:断点要打很多个地方)。

【行为型】Chain of responsibility模式的更多相关文章

  1. Chain of Responsibility模式

    熟悉VC/MFC的都知道,VC是“基于消息,事件驱动”,消息在VC开发中起着举足轻重的作用.MFC提供了消息的处理的链式处理策略,处理消息的请求将沿着预定好的路径依次进行处理.消息的发送者并不知道该消 ...

  2. Java设计模式(14)责任链模式(Chain of Responsibility模式)

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...

  3. 设计模式(十四)Chain of Responsibility模式

    Chain of Responsibility模式就是当外部请求程序进行某个处理,但程序暂时无法直接决定由哪个对象负责处理时,就需要推卸责任.也就是说,当一个人被要求做什么事时,如果他可以做就自己做, ...

  4. 《图解设计模式》读书笔记6-2 Chain of Responsibility模式

    目录 1. 简介 2. 示例程序 类图 代码 3. 模式的角色和类图 角色 类图 4. 思路拓展 1. 简介 Chain of Responsibility模式是责任链模式,模式的核心就是转移责任.就 ...

  5. 职责链(Chain of Responsibility)模式在航空货运中的运用实例

    设计模式这东西,基本上属于“看懂一瞬间,用会好几年”.只有实际开发中,当某一模式很好的满足了业务需求时,才会有真切的感觉.借用一句<闪电侠>中,绿箭侠教导闪电侠的台词:“不是你碰巧遇到了它 ...

  6. Behavioral模式之Chain of Responsibility模式

    1.意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递改请求,知道有一个对象处理它为止. 2.别名 无 3.动机 考虑一个图形用户界面 ...

  7. C++设计模式实现--职责链(Chain of Responsibility)模式

    一. 概述 职责链模式: 使多个对象都有机会处理请求.从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个样例 员工要求加薪 ...

  8. 设计模式C++描述----05.职责链(Chain of Responsibility)模式

    一. 概述 职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 二. 举个例子 员工要求加薪 ...

  9. 设计模式:chain of responsibility模式

    目的:弱化发出请求的对象和处理请求对象的之间的关系 理解:每个处理请求的对象仅仅只关注自己能处理的请求,不关系其他请求 优点: 无需一个管理类来匹配所有的请求,更灵活 责任链可以动态的调整 Andor ...

随机推荐

  1. 由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考

    背景   我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求).调度任务(常规分析需求),两者均通过我们的 ...

  2. Android新浪微博客户端(六)——Home界面的ListView

    原文出自:方杰|http://fangjie.info/?p=184转载请注明出处 最终效果演示:http://fangjie.info/?page_id=54该项目代码已经放到github:http ...

  3. vector的含义

    数学中,vector(向量)表示一个量,由大小和方向构成.比如坐标中的一个带箭头的线段 -- 它1厘米长,正弦值六分之一π(30度角). 计算机的c++.java中,vector表示一种一维的数组.比 ...

  4. UITouch附加

    框架 /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKNode.h 概览 重要提示:这是一个初步的 ...

  5. ListView列表拖拽排序

    ListView列表拖拽排序能够參考Android源代码下的Music播放列表,他是能够拖拽的,源代码在[packages/apps/Music下的TouchInterceptor.java下]. 首 ...

  6. 定时关机命令——shutdown

    通常会用到的定时关机命令有两种: Shutdown -s -t 36001小时后自己主动关机(3600秒) at 12:00 Shutdown -s 12:00自己主动关闭计算机 系统定时关机: Wi ...

  7. 经典算法:快排的Javascript版本

    function swap(arr,l,r){ var temp=arr[l]; arr[l]=arr[r]; arr[r]=temp; } function partition(arr,camp,l ...

  8. jquery中prop()方法和attr()方法的区别(转)

    jquery1.6中新加了一个方法prop(),一直没用过它,官方解释只有一句话:获取在匹配的元素集中的第一个元素的属性值. 官方例举的例子感觉和attr()差不多,也不知道有什么区别,既然有了pro ...

  9. 使用symbolicatecrash分析crash文件

    对于我们iOS开发者来说,最心碎的事莫过于苹果审核一个星期后上架app store,而第二天就报出闪退bug.一周前我刚经历过,而且最坑的是由于第一次做个人开发,经验不足,没有集成友盟的分析SDK,还 ...

  10. [转] 在 Linux 中怎样使用cp命令合并目录树

    PS:通过cp -r --link a/* b/* merged 硬链接不需要复制 怎样将两个布局相似的目录树合并成一个新的目录树?为理解该问题让我们思考下面的例子. 假设 dir1 和 dir2 目 ...