《设计模式》— 行为型模式 — 责任链模式

news/2024/5/19 15:19:20 标签: 责任链模式, 开发语言, 设计模式

设计模式》— 行为型模式 — 责任链模式

  • 一、动机
  • 二、适用性
  • 三、结构
  • 四、参与者
    • 1、Handler
    • 2、ConcreteHandler
    • 3、Client
  • 五、效果
    • 1、降低耦合度
    • 2、增加了给对象指派职责的灵活性
    • 3、不保证被接受
  • 六、实现
    • 1、实现后继者链
    • 2、连接后继者
    • 3、表示请求
  • 七、应用

一、动机

考虑一个图形用户界面的上下文有关的帮助机制。用户在界面的任一部分点击就可以得到帮助信息,所提供的帮助依赖于点击的是界面的哪一部分及其上下文。例如,对话框中按钮的帮助信息就可能和主窗口中类似的按钮不同。如果对那一部分界面没有特定的帮助信息,那么帮助系统应该显示一个关于当前上下文的较一般的帮助信息。

因此,很自然地,应根据普遍性从最特殊到最普遍的顺序来组织帮助信息。而且,很明显,在这些用户界面对象中会有一个对象来处理帮助请求,至于是哪一个对象则取决于上下文以及可用的帮助具体到何种程度。

这里的问题是提交帮助请求的对象并不明确知道谁是最终提供帮助的对象。我们要有一种办法将提交帮助请求的对象与可能提供帮助信息的对象解耦 —— 责任链模式

这一模式的想法是,给多个对象处理一个请求的机会,从而解耦发送者和接受者。该请求沿对象链传递直至其中一个对象处理它。从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不明确的知道哪一个对象将会处理它 —— 因此我们说该模式有一个隐式的接受者。

要沿链转发请求,并保证接受者为隐式的,每个在链上的对象都有一致的处理请求和访问链上后继者的接口。例如,帮助系统可以定义一个带有相应的 handleHelp 操作的 HelpHandler 类。HelpHandler 可以是所有候选对象类的父类,或者它可被定义为一个混入类。这样想处理帮助请求的类就可以将 HelpHandler 作为其父类,如下图所示。
在这里插入图片描述
这里我们可以在 HelpHandler 类中保存一个 handler,用于保存处理该请求的后继类对象。

二、适用性

  • 有多个对象可以处理一个请求,哪个对象处理该请求运行是自动确定。
  • 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可处理一个请求的对象集合应该被动态指定。

三、结构

在这里插入图片描述

四、参与者

1、Handler

  • 定义一个处理请求的接口。
  • 实现后继链。

2、ConcreteHandler

  • 处理它所负责的请求。
  • 可访问它的后继者。
  • 如果可处理该请求,就处理之;否则将请求转发给它的后继者。

3、Client

提交请求

五、效果

1、降低耦合度

该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需要知道该请求会被正确地处理。接受者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构。

2、增加了给对象指派职责的灵活性

当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。

3、不保证被接受

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

六、实现

1、实现后继者链

有两种方式可以实现后继者链:

  • 定义新的链接(可以在基类中定义)
  • 使用已有的链接

我们前面讨论了如何通过定义新的链接实现后继者链。此外,在组合模式中,我们可以通过将父组件引用设置为后继者实现职责链。

2、连接后继者

如果没有已有的引用可定义一个链,那么你必须自己引入它们。这种情况下 Handler 不仅定义该请求的接口,通常也维护后继者。这样 handler 就提供了 handleRequest 的默认实现:handlerRequest 向后继者转发请求。如果 ConcreteHandler 对该请求不感兴趣,它不需要重定义转发操作,因为它的默认实现进行无条件的转发。

3、表示请求

可以有不同的方式表示请求。最简单的形式就是使用硬编码,例如我们前面直接调用 handleHelp 来处理帮助的请求,并调用后继者的响应方法进行转发。这种形式方便且很安全,但是不易扩充。

另一种方法是选择使用一个处理函数。我们可以通过不同的枚举常量来区分不同类型的请求。我们可以通过增加枚举类型的常量值来增加请求。但是发送发和接受方要在如何对请求编码上达成一致。在这种实现中,我们可以使用一个类封装请求对象,并暴露一个接口用于获取请求类型。

七、应用

责任链模式最常见的应用就是在事件处理的系统中。无论是在 windows 系统中,还是浏览器交互中,用户的点击事件被触发后并不是仅被当前点击的窗体捕获,而是会沿着其父对象(或者子对象,取决于事件传递的模式)继续传递,直到到达末尾或有窗体显式地阻止该事件继续传递。

此外,现在基本所有语言都支持异常。异常处理其实也应用了责任链模式。当异常发生时,会发生栈接退。该异常会在栈上不断地向调用函数传递,直到有函数捕获了该异常,或者最终被系统的异常处理函数捕获,调用 terminate 终止进程。


http://www.niftyadmin.cn/n/1340297.html

相关文章

《设计模式》— 行为型模式 — 状态模式

《设计模式》— 行为型模式 — 状态模式一、动机二、适用性三、结构四、参与者1、Context2、State3、Concrete State五、协作六、效果1、将与特定状态相关的行为局部化,并且将不同状态的行为分割开来2、使得状态转换显式化3、State 对象可被共享七、实现1、谁定义转…

IOS入门之Swift语言(一)

经过不断的努力,小哥也买了台苹果设备,终于可以开始我的IOS之旅了,说来确实令人苦恼,为了学习IOS我这着贫农阶级,省了几个月的零花钱,外加向亲朋好友求救,最终痛下心扉,卖了台MAC pr…

《设计模式》— 行为型模式 — 模板方法模式

《设计模式》— 行为型模式 — 模板方法模式一、动机二、适用性三、结构四、效果五、实现1、使用访问控制2、尽量减少原语操作3、命名约定六、应用一、动机 考虑一个提供 Application 和 Document 类的应用框架。Application 类负责打开一个已有的以外部形式存储的文档&#x…

C++ Primer 学习笔记_53_类和数据抽象 --友元、static员

分类--友元、static成员一、友元友元机制同意一个类将对其非公有成员的訪问权授予指定的函数或类(对未被授权的函数或类,则阻止其訪问);友元的声明以keywordfriend開始,可是它仅仅能出如今类定义的内部。友元声明能够出…

《设计模式》— 行为型模式 — 命令模式

《设计模式》— 行为型模式 — 命令模式一、动机二、适用性三、结构四、参与者1、Command2、ConcreteCommand3、Client4、Invoker5、Receiver五、协作六、效果七、实现1、一个命令对象应达到何种智能程度2、支持撤销和重做3、使用C模板类八、应用一、动机 有时必须向某对象提交…

web即使通讯-IM

IM实现方式:node.js转载于:https://blog.51cto.com/hanchengen/1704149

《设计模式》— 行为型模式 — 观察者模式

《设计模式》— 行为型模式 — 观察者模式一、动机二、适用性三、结构四、参与者1、Subject2、Observer3、ConcreteSubject4、ConcreteObserver五、协作六、效果1、目标和观察者间的抽象耦合2、支持广播通信3、意外的更新七、实现1、创建目标到其观察者之间的映射2、观察多个目…

二叉树的友好实现(转)

1. 引言 前些天数据结构课讲到了二叉树。学校使用的教材是《数据结构(Java版)(第4版,叶核亚)》。总觉得书中给出的二叉树(包括之前学的线性表)的实现方式不太“优雅”(面向对象&…