责任链模式
定义
责任链模式,是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。避免了请求发送者与多个请求处理者耦合在一起

与许多其他行为设计模式一样, 责任链会将特定行为转换为被称作处理者的独立对象。 在上述示例中, 每个检查步骤都可被抽取为仅有单个方法的类, 并执行检查操作。 请求及其数据则会被作为参数传递给该方法。
责任链会模式建议你将这些处理者连成一条链。 链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。 除了处理请求外, 处理者还负责沿着链传递请求。 请求会在链上移动, 直至所有处理者都有机会对其进行处理。
最重要的是: 处理者可以决定不再沿着链传递请求, 这可高效地取消所有后续处理步骤。
处理者会在进行请求处理工作后决定是否继续沿着链传递请求。 如果请求中包含正确的数据, 所有处理者都将执行自己的主要行为, 无论该行为是身份验证还是数据缓存。
责任链模式结构

- 处理者 (Handler) 声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。
- 基础处理者 (Base Handler) 是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。
- 具体处理者 (Concrete Handlers) 包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
- 客户端 (Client) 可根据程序逻辑一次性或者动态地生成链。 值得注意的是, 请求可发送给链上的任意一个处理者, 而非必须是第一个处理者。
责任链模式适合应用场景
- 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
- 该模式能将多个处理者连接成一条链。 接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。 这样所有处理者都有机会来处理请求。
- 当必须按顺序执行多个处理者时, 可以使用该模式。
- 无论你以何种顺序将处理者连接成一条链, 所有请求都会严格按照顺序通过链上的处理者。
- 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。
- 如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序。
实现方式
- 声明处理者接口并描述请求处理方法的签名。确定客户端如何将请求数据传递给方法。 最灵活的方式是将请求转换为对象, 然后将其以参数的形式传递给处理函数。
2 . 为了在具体处理者中消除重复的样本代码, 你可以根据处理者接口创建抽象处理者基类。
该类需要有一个成员变量来存储指向链上下个处理者的引用。 你可以将其设置为不可变类。 但如果你打算在运行时对链进行改变, 则需要定义一个设定方法来修改引用成员变量的值。为了使用方便, 你还可以实现处理方法的默认行为。 如果还有剩余对象, 该方法会将请求传递给下个对象。 具体处理者还能够通过调用父对象的方法来使用这一行为。
- 依次创建具体处理者子类并实现其处理方法。 每个处理者在接收到请求后都必须做出两个决定:
- 是否自行处理这个请求。
- 是否将该请求沿着链进行传递。
- 客户端可以自行组装链, 或者从其他对象处获得预先组装好的链。 在后一种情况下, 你必须实现工厂类以根据配置或环境设置来创建链。
- 客户端可以触发链中的任意处理者, 而不仅仅是第一个。 请求将通过链进行传递, 直至某个处理者拒绝继续传递, 或者请求到达链尾。
- 由于链的动态性, 客户端需要准备好处理以下情况:
- 链中可能只有单个链接。
- 部分请求可能无法到达链尾。
- 其他请求可能直到链尾都未被处理。
与其他模式的关系
-
责任链模式、 命令模式、 中介者模式和观察者模式用于处理请求发送者和接收者之间的不同连接方式:
- 责任链按照顺序将请求动态传递给一系列的潜在接收者, 直至其中一名接收者对请求进行处理。
- 命令在发送者和请求者之间建立单向连接。
- 中介者清除了发送者和请求者之间的直接连接, 强制它们通过一个中介对象进行间接沟通。
- 观察者允许接收者动态地订阅或取消接收请求。
-
责任链 通常和组合模式结合使用。 在这种情况下, 叶组件接收到请求后, 可以将请求沿包含全体父组件的链一直传递至对象树的底部。
-
责任链的管理者可使用命令模式实现。 在这种情况下, 你可以对由请求代表的同一个上下文对象执行许多不同的操作。
还有另外一种实现方式, 那就是请求自身就是一个命令对象。 在这种情况下, 你可以对由一系列不同上下文连接而成的链执行相同的操作。
-
责任链和装饰模式的类结构非常相似。 两者都依赖递归组合将需要执行的操作传递给一系列对象。 但是, 两者有几点重要的不同之处。
责任链的管理者可以相互独立地执行一切操作, 还可以随时停止传递请求。 另一方面, 各种装饰可以在遵循基本接口的情况下扩展对象的行为。 此外, 装饰无法中断请求的传递。
相关文章
-
设计模式——模板方法模式
-
如何设计 API: 基本指南 + 最佳实践
-
企业架构 架构治理 金融IT架构 JAVA技术 大数据 Devops 低代码;生活 思维 健身
-
企业架构、技术方案、行业资料下载(持续更新)