C++设计模式——职责链模式
什么是职责链模式?
在GOF的《设计模式:可复用面向对象软件的基础》一书中对职责链模式是这样说的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,直到有一个对象处理它为止;如下图:

对于每个角色,他们都有他们的职责;当我提交了休假申请时,项目经理需要判断,看看自己能否处理,如果休假超过了2个小时,那么项目经理就不能处理了;项目经理将这个请求提交到项目主管,项目主管判断部门经理在不在,如果部门经理在,项目主管就不能处理了;最后,我的休假申请就到了部门经理那里了,由他亲自审批。可以很明显的看到,项目经理、项目主管和部门经理都有可能处理我的休假申请,我的请求沿着这条链一直走下去,直到有人处理了我的请求。
UML类图

Handler:定义了一个处理请求的接口;其它类如果需要处理相同的请求,可以实现该接口就好了;
ConcreteHandler:处理它所负责的请求,如果可处理该请求,就处理掉这个请求;否则将该请求转发给它的下一个可以处理该请求的对象,所以它必须能访问它的下一个可以处理同样请求的对象;
Client:向处理对象提出具体的请求。
当客户提交一个请求时,请求沿着一条链传递,直至有一个ConcreteHandler对象负责处理它。
使用场合
- 有多个的对象可以处理一个请求,由哪个对象处理该请求是在运行时刻自动确定的;
- 如果想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
- 可以处理一个请求的对象集合应被动态指定。
代码实现
#include <iostream>
using namespace std; #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } class HolidayRequest
{
public:
HolidayRequest(int hour) : m_iHour(hour){}
int GetHour() { return m_iHour; }
private:
int m_iHour;
}; // The holiday request handler interface
class Manager
{
public:
virtual bool HandleRequest(HolidayRequest *pRequest) = ;
}; // Project manager
class PM : public Manager
{
public:
PM(Manager *handler) : m_pHandler(handler){}
bool HandleRequest(HolidayRequest *pRequest)
{
if (pRequest->GetHour() <= || m_pHandler == NULL)
{
cout<<"PM said:OK."<<endl;
return true;
}
return m_pHandler->HandleRequest(pRequest);
}
private:
Manager *m_pHandler;
}; // Department manager
class DM : public Manager
{
public:
DM(Manager *handler) : m_pHandler(handler){}
bool HandleRequest(HolidayRequest *pRequest)
{
cout<<"DM said:OK."<<endl;
return true;
} // The department manager is in?
bool IsIn()
{
return true;
}
private:
Manager *m_pHandler;
}; // Project supervisor
class PS : public Manager
{
public:
PS(Manager *handler) : m_pHandler(handler){}
bool HandleRequest(HolidayRequest *pRequest)
{
DM *pDM = dynamic_cast<DM *>(m_pHandler);
if (pDM != NULL)
{
if (pDM->IsIn())
{
return pDM->HandleRequest(pRequest);
}
}
cout<<"PS said:OK."<<endl;
return true;
}
private:
Manager *m_pHandler;
};
int main()
{
DM *pDM = new DM(NULL);
PS *pPS = new PS(pDM);
PM *pPM = new PM(pPS);
HolidayRequest *pHolidayRequest = new HolidayRequest();
pPM->HandleRequest(pHolidayRequest);
SAFE_DELETE(pHolidayRequest); pHolidayRequest = new HolidayRequest();
pPM->HandleRequest(pHolidayRequest); SAFE_DELETE(pDM);
SAFE_DELETE(pPS);
SAFE_DELETE(pPM);
SAFE_DELETE(pHolidayRequest);
}
优缺点
- 降低耦合度;职责链模式使得一个对象不用知道是哪一个对象处理它的请求。对象仅需要知道该请求会被正确的处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需要知道链的结构;
- 增强了给对象指派职责的灵活性;当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责;
- 不保证被接受,既然一个请求没有明确的接收者,那么就不能保证它一定会被处理;该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
总结
职责链模式在实现时,需要处理好它的后继者的问题,就是说,如果我不处理这个请求,那么我将把这个请求发给谁去处理呢?同时,职责链模式在实现时,它的链的形状并不是由职责链本身建立和维护的,而是由客户进行创建的,由客户指定每一个处理者的后继者是谁。这就大大的提高了职责链的灵活性。在实际中,我们也可以将职责链模式与组合模式相结合,一个构件的父构件可以作为它的后继者。
C++设计模式——职责链模式的更多相关文章
- 17. 星际争霸之php设计模式--职责链模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- JAVA 设计模式 职责链模式
用途 职责链模式 (Chain Of Responsibility) 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系. 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个 ...
- 深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传 ...
- 设计模式:职责链模式(Chain of Responsibility)
去年参加校招要到长沙来,这个对于我来说不是特别喜欢(但又必须的来,谁叫咱不是985.211的娃呢),但是对于某些人来说就是福音了.大四还有课,而且学校抓的比较严,所以对于那些想翘课的人来说这个是最好不 ...
- C#设计模式——职责链模式(Chain Of Responsibility Pattern)
一.概述 在软件开发中,某一个对象的请求可能会被多个对象处理,但每次最多只有一个对象处理该请求,对这类问题如果显示指定请求的处理对象,那么势必会造成请求与处理的紧耦合,为了将请求与处理解耦,我们可以使 ...
- C++设计模式---职责链模式
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿这条链传递该请求,直到有一个对象处理它为止. 这里发出这个请求的客户端并不知道这当中的哪一 ...
- javascript设计模式——职责链模式
前面的话 职责链模式的定义是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.职责链模式的名字非常形象,一 ...
- java设计模式---职责链模式
职责链的本质:分离职责,动态组合 样例: /** * 定义职责对象的接口 * */ public abstract class Handler { protected Handler successo ...
- 设计模式 | 职责链模式(Chain of responsibility)
定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连城一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 结构:(书中图,侵删) 一个抽象的处理者 若干 ...
随机推荐
- Spring Security Oauth2 的配置
使用oauth2保护你的应用,可以分为简易的分为三个步骤 配置资源服务器 配置认证服务器 配置spring security 前两点是oauth2的主体内容,但前面我已经描述过了,spring sec ...
- 《React Native 精解与实战》书籍连载「Android 平台与 React Native 混合开发」
此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...
- jQuery对象与DOM对象之间的转换(转)
原文:https://www.cnblogs.com/lsy0403/p/5907084.html 什么是DOM对象 使用JavaScript中的方法获取页面中的元素返回的对象就是dom对象.比如使用 ...
- 关于vue打包是因代码校验报错
单个文件中: 1./* eslint - disable */ 2./* eslint-disable no-new */ 当然也支持全局: 3.bulid > webpack.base.con ...
- UVA 10118 Free Candies
https://vjudge.net/problem/UVA-10118 题目 桌上有4堆糖果,每堆有$N$($N\leqslant 40$)颗.有个熊孩子拿了个可以装5颗糖的篮子,开始玩无聊的装糖游 ...
- 第六十四天 JS基础操作
一.分支结构 1.if语句 if基础语句 if(条件表达式){ 代码块: } // 当条件表达式结果为true,会执行代码块:反之不执行 // 条件表达式可以为普通表达式 // 0.undefined ...
- BBS 502 BadGateway 原因分析
说明: LNMP架构. crontab里有每隔20分钟重启php的任务:然后我用python写了个每1分钟检测php-cgi进程是否存在的脚本,如果不存在则调用重启php的脚本,并邮件通知管理员.cr ...
- C++ 动态链接库 DLL 的一些笔记
DLL 文件源代码: // test.h #ifdef TEST_EXPORTS #define TEST_API __declspec(dllexport) #endif class TEST_AP ...
- class09
class09 四川菜很辣. Sichuan cuisine is very spicy. 那个汤是凉的. That soup is cold. 这茶很烫. This tea is very hot. ...
- 【nginx】nginx日常命令
看下nginx命令的帮助信息 [root@localhost oa_workflow_test]# /usr/local/nginx/sbin/nginx -h nginx version: ngin ...