第 10 章 责任链模式
开发一个应用时,多数时候我们都能预先知道哪个方法能处理某个特定请求。然而,情况并非总是如此。
责任链(Chain of Responsibility)模式用于让多个对象来处理单个请求时,或者用于预先不知道应该由哪个对象(来自某个对象链)来处理某个特定请求时。其原则如下所示:
存在一个对象链(链表、树或任何其他便捷的数据结构)。
我们一开始将请求发送给链中的第一个对象。
对象决定其是否要处理该请求。
对象将请求转发给下一个对象。
重复该过程,直到到达链尾。
10.1 现实生活的例子
ATM 机以及及一般而言用于接收/返回钞票或硬币的任意类型机器(比如,零食自动贩卖机)都使用了责任链模式。
10.2 软件的例子
Java 的 servlet 过滤器是在一个 HTTP 请求到达目标处理程序之前执行的一些代码片段。在使用 servlet 过滤器时,有一个过滤器链,其中每个过滤器执行一个不同动作(用户身份验证、记日志、数据压缩等),并且将请求转发给下一个过滤器直到链结束;如果发生错误(例如,连续三次身份验证失败)则跳出处理流程。
Apple 的 Cocoa 和 Cocoa Touch 框架使用责任链来处理事件。在某个视图接收到一个其并不知道如何处理的事件时,会将事件转发给其超视图,直到有个视图能够处理这个事件或者视图链结束。
10.3 应用案例
通过使用责任链模式,我们能让许多不同对象来处理一个特定请求。在我们预先不知道应该由哪个对象来处理某个请求时,这是有用的。其中一个例子是采购系统。
另一个责任链可以派上用场的场景是,在我们知道可能会有多个对象都需要对同一个请求进行处理之时。这在基于事件的编程中是常有的事情。
不过应该注意,如果所有请求都能被单个处理程序处理,责任链就没那么有用了,除非确实不知道会是哪个程序处理请求。这一模式的价值在于解耦。客户端与所有处理程序(一个处理程序与所有其他处理程序之间也是如此)之间不再是多对多关系,客户端仅需要知道如何与链的起始节点(标头)进行通信。
10.4 实现
使用 Python 实现责任链模式有许多种方式,Vespe 的实现以地道的 Python 风格使用动态分发来处理请求。
参考实现一个简单的事件系统:
Last updated