责任链的目的是通过特定的设计对请求者和接收者之间进行解耦,请求者调用操作的对象,接收者接收请求并执行相关操作,通过解耦请求者不需要关心接收者的接口,同时也可增强职责的灵活性,通过改变链内的成员或调用次序,允许动态新增或删除责任。

作用

责任链模式通过将多个对象连成链式模式,并沿着这个链传递命令或者请求,直到有对象处理它为止。

类视图

实现

我们还是取比较经典的员工请假的例子。员工为请假的请求者,接收者分别从项目经理、部门经理、公司经理这几个层级,员工向上进行请假操作,首先传递给项目经理,项目经理在处理时分为两种情况,如果项目经理人在公司,并且员工的请假天数满足请假的审批权限范围,则给予审批,反之则申请上级进行处理。

当然我们也可以制定自己的特殊规则,比如经理级别的接收者如果人不在,就不能向上进行请求,比如开可以增加请假的事由以供经理进行判断是否满足请假要求等,这些都可以根据实际情况进行扩充,感兴趣可以自己实现。

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路由(链式)和广播模式(群发)的实现,这下大家就明白了吧;

当然也请注意链式结构的效率问题,对于层级最好还是加以控制。

应用场景

  1. 基于链式的请求和应答的结构;
  2. 发送者并不知道在链中的哪个对象会响应请求;
  3. 责任链中的每一个对象都有职责绝对是否对请求进行响应

转载于:https://www.cnblogs.com/chencarl/p/8762521.html

设计模式之责任链模式(Chain of Responsibility )相关推荐

  1. 乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)

    原文:乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 责任链模式(Chain of ...

  2. 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern) 介绍 为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求, ...

  3. 责任链模式(Chain of Responsibility)

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

  4. 责任链模式 Chain of Responsibility

    责任链模式是一种设计模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最 ...

  5. [设计模式-行为型]责任链模式(Chain of Responsibility)

    概括 名称 Chain of Responsibility 结构 动机 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一 ...

  6. java 事件链_Java设计模式——责任链模式(Chain of Responsibility)

    责任链 责任链模式通俗来说就是关联一串能够处理事务的对象,使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. ...

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

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

  8. 十八、责任链模式 ( Chain of Responsibility)

    责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链 责任链模式给予请求的类型,对请求的发送者和接收者进行解耦 责任链模式中通常每个接收者都包含对 ...

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

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

  10. 设计模式(24)-----责任链模式

    责任链模式(chain of responsibility) 定义 责任链模式是对象的行为模式.使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系.将这些对象连成一条链,沿着这条链 ...

最新文章

  1. 子元素是字典列表转成字典
  2. Python中@staticmethod和@classmethod之间的区别
  3. 如何在IIS上配置多个网站,及网站发布配置讲解
  4. 算法题存档20190206
  5. configure 查看默认安装路径
  6. 微软发表IE浏览器 F1漏洞安全公告
  7. jq将php时间戳转化日期格式,JQuery将时间戳转换为时间
  8. 记录一下Mac浏览器劫持searchbaron.com的经历
  9. word自动生成目录如何设置第一页和页码不齐问题
  10. 利用R语言ggplot2包制作金字塔图,展示人口结构数据
  11. python 知乎 合并 pdf_怎么把多个pdf合并在一起?
  12. 北航计算机组成实验课,北航计算机组成实验Project4
  13. 《Android 应用案例开发大全(第二版)》——1.5节第一个Android程序——Hello Android...
  14. 【每天听见吴晓波-2016-07-04】上海房价未来五年还会翻番
  15. 谷歌浏览器按F12调试js代码的时候找不到代码在哪
  16. 编程基本功训练:流程图画法及练习
  17. python发短信 金山_Python爬虫基础练习(四) 金山翻译爬取(进阶篇)
  18. 如何提高节点下线速度或避免因节点掉线产生网络风暴?
  19. java计算机毕业设计微服务”架构下新闻头条的设计与实现源码+系统+数据库+lw文档
  20. 20191021 设计图都不会画,还想做”架构师“?

热门文章

  1. update mysql.user set password_使用update命令来修改Mysql的root密码
  2. oracle自增列问题i,Oracle序列 和 SQL SERVER 自增列的问题-oracle
  3. python save保存图片到本地_python爬取网站上的图片并保存到本地
  4. c语言运行程序没有,这个程序怎么运行?为什么显示没有exe??
  5. 社区发现(六)--模块度
  6. linux dd 非常慢,macOS Sierra:dd到USB非常慢,似乎无法使用/ dev / rdisk
  7. “21天好习惯“第一期-2
  8. 【数据库原理实验(openGauss)】金融场景化实验
  9. Azkaban入门简介
  10. scala练习:依据输入的年和月打印该月日历