专栏首页木木玲设计模式 ——— 职责链模式

设计模式 ——— 职责链模式

CHAIN OF RESPONSIBILITY(职责链) ———— 对象行为型模式

意图

使多个对象都有机会处理请求,从而避免请求的转发者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

适用性

  • 如果有多个对象可以处理同一个请求,但是具体由哪个对象来处理该请求,是运行时刻动态确定的。这种情况可以使用职责链模式,把处理请求的对象实现成为职责对象,然后把它们构成一个职责链,当请求在这个链中传递的时候,具体由哪个职责对象来处理,会在运行时动态判断。
  • 如果你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求的话,可以使用职责链模式,职责链模式实现了请求者和接收者之间的解耦,请求者不需要知道究竟是哪一个接收者对象来处理了请求。
  • 如果想要动态指定处理一个请求的对象集合,可以使用职责链模式,职责链模式能动态的构建职责链,也就是动态的来决定到底哪些职责对象来参与到处理请求中来,相当于是动态指定了处理一个请求的职责对象集合。

结构

  • Handler(职责接口) 通常在这里定义处理请求的方法,可以在这里实现后继链。
  • ConcreteHandler(具体职责类) 在这个类里面,实现对在它职责范围内请求的处理,如果不处理,就继续转发请求给后继者。
  • Client(职责链的客户端) 向链上的具体处理者对象提交请求,让职责链负责处理。

对职责链模式实现的深入探讨

  • 实现后继者链 ① 定义新的链接;② 使用已有的链接 当已有的链接能够支持你所需的链时,完全可以使用它们。这样你不需要明确定义链接,而且可以节省空间。但如果该结构不能反映应用所需的职责链,那么你必须定义额外的链接。 比如,当前职责处理对象引用了一个"职责链_One”作为它的后继者链,而这个"职责链_One”中已经存在了它自己的后继者链,假设这个"职责链_One”完整的链为“A ——> B ——> C”。这样当前的职责处理对象其实并没有明确的指定“A ——> B ——> C”这个链,而是通过组合的模式复用了该链。
  • 隐式接收者 当客户端发出请求的时候,客户端并不知道谁会真正处理他的请求,客户端只知道他提交请求的第一个对象。从第一个处理对象开始,整个职责链里面的对象,要么自己处理请求,要么继续转发给下一个接收者。 也就是对于请求者而言,并不知道最终的接收者是谁,但是一般情况下,总是会有一个对象来处理的,因此称为隐式接收者。
  • 一个职责链处理多种请求 ① 在Handler中定义不同的方法表示不同的请求。这种形式方便而且安全,但你只能转发Handler类定义的固定的一组请求。 ② 定义一个请求对象类(Request)来封装请求的类型和参数。Handler中依旧指定义一个通用的请求方法,该方法不区分请求的类型,所以的请求都是调用该方法,具体的请求类型通过请求对象(Request)中的请求类型属性来标识。那么在具体的接收者中就可以通过Request中标识的不同请求类型进行不同的逻辑处理,处理逻辑依旧是要么处理该请求,要么将该Request对象传递给下一个接收者。
  • 连接后继者 可以在Handler中定义一个请求的缺省实现,即,将请求传递给后继者(如果有后继者的话)。这样一来如果ConcreteHandler子类对该请求不感兴趣,则不需要重定义请求处理操作,因为它的缺省实现会进行无条件的转发。

优缺点

优点: ① 降低耦合度 在职责链模式里面,请求者并不知道接收者是谁,也不知道具体如何处理,请求者只是负责向职责链发出请求就可以了。接收者和请求者都没有对象的明确的信息,且链中的对象不需要知道链的结构。 结果是,职责链可简化接收者对象的相互连接。它们仅需保持一个指向其后续者的引用,而不需要保持它所有的候选接收者的引用。 ② 增强了给对象指派职责的灵活性 当在接收者中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。

缺点: ① 不保证被接受 既然一个请求没有明确的接收者,那么就不能保证它一定会被处理 ———— 该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有正确配置而得不到处理。

功能链

在实际开发中,经常会出现一个把职责链稍稍变形的用法。在标准的职责链中,一个请求在职责链中传递,只要有一个对象处理了这个请求,就会停止。 现在稍稍变一下,改成一个请求在职责链中传递,每个职责对象负责处理请求的某一方面的功能,处理完成后,不是停止,而是继续向下传递请求,当请求通过很多职责对象处理过后,功能也就处理完了,把这样的职责链称为功能链。

相关模式

  • 职责链模式 VS 组合模式 这两个模式可以组合使用。 可以把职责对象通过组合模式来组合,这样可以通过组合对象自动递归的向上调用,由父组件作为子组件的后继,从而形成链。
  • 职责链模式 VS 装饰模式 这两个模式相似,从某个角度讲,可以相互模拟实现对方的功能。 装饰模式是在已有的功能上增加新的功能,多个装饰器之间会有一定的联系;而职责链模式的各个职责对象实现的功能,相互之间是没有关联的,是自己实现属于自己处理的那一份功能。
参考

《设计模式:可复用面向对象软件的基础》 《研磨设计模式》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式 ——— 中介者模式

    tomas家的小拨浪鼓
  • ConcurrentHashMap (JDK7) 详解

    tomas家的小拨浪鼓
  • 第十二章 机器学习系统设计

    为了应用‘监督学习’,首先需要想到的是,如何表示’邮件的特征向量x’,通过特征向量 x 和分类标签 y。我们就能训练一个分类器。比如使用逻辑回归的方法。 ?有...

    tomas家的小拨浪鼓
  • 围棋天团告负!1v5英雄“狗”背后的原理概括

    今天,中国围棋峰会进行到了第四天,AlphaGo挑战两种未曾体验过的比赛:人机配对赛和1v5的团体赛。 对于全新的比赛形式,棋圣聂卫平与AlphaGo之父哈萨比...

    AI科技大本营
  • Greenplum资源队列初识

    在Greenplum的4.x版本之后,加入了资源队列的概念,其主要作用就是限制用户或者单个SQL对资源的消耗。避免出现消耗过多资源,影响其他用户或者SQL计算。...

    洛杉矶
  • Calico在Openshift上的工作原理与配置步骤:第一篇

    由于篇幅和时间有限,本文还会有第二篇。 一、Openshift支持的各种SDN CNI Openshift Container Platform(简称OCP),...

    魏新宇
  • 【邓侃】DeepMind 机器理解文本 NLP 技术复现与解析

    【新智元导读】 本文对 DeepMind 的让计算机读懂文本、回答问题的深度学习技术进行复现与解析。文章对DeepMind的整个技术思路进行了清晰的重构:从问...

    新智元
  • 微服务框架开源项目

    https://gitee.com/zlt2000/microservices-platform

    陶陶技术笔记
  • HTTP协议详解

    利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则从链路层往上走。如下:

    小柒吃地瓜
  • 学界 | 新型实时形义分割网络ShuffleSeg:可用于嵌入式设备

    选自arXiv 作者:Mostafa Gamal等 机器之心编译 参与:Panda 表现优良的卷积神经网络往往需要大量计算,这在移动和嵌入式设备以及实时应用上是...

    机器之心

扫码关注云+社区

领取腾讯云代金券