https://blog.csdn.net/CoderAldrich/article/details/83183388

什么是职责链模式?

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

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

UML类图

Handler:定义了一个处理请求的接口;其它类如果需要处理相同的请求,可以实现该接口就好了;
ConcreteHandler:处理它所负责的请求,如果可处理该请求,就处理掉这个请求;否则将该请求转发给它的下一个可以处理该请求的对象,所以它必须能访问它的下一个可以处理同样请求的对象;
Client:向处理对象提出具体的请求。

当客户提交一个请求时,请求沿着一条链传递,直至有一个ConcreteHandler对象负责处理它。

使用场合

  1. 有多个的对象可以处理一个请求,由哪个对象处理该请求是在运行时刻自动确定的;
  2. 如果想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
  3. 可以处理一个请求的对象集合应被动态指定。

代码实现

#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) = 0;
};// Project manager
class PM : public Manager
{
public:PM(Manager *handler) : m_pHandler(handler){}bool HandleRequest(HolidayRequest *pRequest){if (pRequest->GetHour() <= 2 || 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(10);pPM->HandleRequest(pHolidayRequest);SAFE_DELETE(pHolidayRequest);pHolidayRequest = new HolidayRequest(2);pPM->HandleRequest(pHolidayRequest);SAFE_DELETE(pDM);SAFE_DELETE(pPS);SAFE_DELETE(pPM);SAFE_DELETE(pHolidayRequest);
}

优缺点

  1. 降低耦合度;职责链模式使得一个对象不用知道是哪一个对象处理它的请求。对象仅需要知道该请求会被正确的处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需要知道链的结构;
  2. 增强了给对象指派职责的灵活性;当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责;
  3. 不保证被接受,既然一个请求没有明确的接收者,那么就不能保证它一定会被处理;该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。

总结

职责链模式在实现时,需要处理好它的后继者的问题,就是说,如果我不处理这个请求,那么我将把这个请求发给谁去处理呢?同时,职责链模式在实现时,它的链的形状并不是由职责链本身建立和维护的,而是由客户进行创建的,由客户指定每一个处理者的后继者是谁。这就大大的提高了职责链的灵活性。在实际中,我们也可以将职责链模式与组合模式相结合,一个构件的父构件可以作为它的后继者。

C++设计模式14——职责链模式相关推荐

  1. 【设计模式】—— 职责链模式ChainOfResponsibility

    模式意图 避免请求的发送者,和接受者过度的耦合在一起.一个请求者只需要发送一个请求即可,它的请求具体由后面哪个对象进行响应,并不需要关心.而请求的接受者可以自己处理它,也可以把它像链条一样向后传. 因 ...

  2. python设计模式案例分析_Python设计模式之职责链模式原理与用法实例分析

    本文实例讲述了Python设计模式之职责链模式原理与用法.分享给大家供大家参考,具体如下: 职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接 ...

  3. 设计模式之职责链模式应用例题

    设计模式之职责链模式应用例题 题目描述 类结构图及相关说明 程序代码 运行结果 题目描述 在军队中,一般根据战争规模的大小和重要性由不同级别的长官(Officer)来下达作战命令,情报人员向上级递交军 ...

  4. 【设计模式】职责链模式(C#)

    [设计模式]职责链模式 1.概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同.例如,公司员工请假或者加薪,可处理的领导有HR.部门负责人.副总经理. ...

  5. 设计模式之职责链模式(Chain of Responsibility)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. JBPM与设计模式之职责链模式

    上篇我们了解并学习了JBPM的长事务实现,其中用到了设计模式中的职责链模式和命令模式:这块还是很有厚重感的,我们可以从中学到很多的东西:今天我们先来学习一下职责链模式. 职责链模式定义 使多个对象都有 ...

  7. 设计模式之职责链模式、减小了因为分支带来的耦合

    1. 定义 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一 ...

  8. 设计模式复习-职责链模式

    #pragma once #include "stdafx.h" #include<set> #include<string> #include<io ...

  9. 『设计模式』职责链模式(Chain of Responsibility) 可怜的加薪、请假之路

    23种设计模式+额外常用设计模式汇总 (持续更新) 问题抽象 客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的. 对于客户端而言,无所谓谁来处理,反正有对象处理就 ...

最新文章

  1. CentOS7.4下建立DNS主从服务器(二)
  2. GeneXus 图片的创建与删除1
  3. halcon算子盘点:Chapter 15灰度分割
  4. 调查谋杀案以换取Obra Dinn
  5. 谷粒商城三阶段课件_苏科版初中物理九年级上册二、变阻器公开课优质课课件教案视频...
  6. redisTemplate.opsForValue()中方法讲解
  7. Java基础-this关键字和构造方法(10)
  8. 用es5实现es6的promise,彻底搞懂promise的原理
  9. Hibernate使用createSqlQuery进行模糊查询时找不到数据
  10. python实现算法改进_运动目标检测vibe算法及其改进Python实现
  11. java实习报告_Java实习报告总结3篇
  12. 塔吊安全智能监控系统智慧工地整体解决方案
  13. Altium designer--软件简介及安装教程(AD)
  14. LDU 2022年2021级测试赛-1
  15. MC34063A MC34063 贴片SOP-8 变换器控制芯片 电流0.8A 1.2A 1.5A
  16. 数据价值应用——数据分析
  17. 谷歌浏览器调用打印机不预览
  18. 整数拆分 python_LeetCode 343. 整数拆分 | Python
  19. mPaaS客户端基线升级踩坑先升到10.1.32再升到10.1.60(iOS)
  20. 【C语言】数组(一维数组、二维数组)

热门文章

  1. 详解RS232、RS485、RS485、串口握手
  2. 【Java基础学习】Java基础中容易忽略点-2
  3. 微信分享打不开分享界面
  4. 前端技术-HTML页面的加载
  5. [python]bokeh学习总结——bokeh.layouts
  6. css 光影掠过文字显现动画
  7. 健身场馆应用软件提供商
  8. 疫情期间广泛运用的远程诊断音视频技术
  9. 任发科:DevOps的前世来生,从《目标》、《凤凰项目》到《持续交付》
  10. 信息化时代下,企业面临的5个数据安全威胁