10.10 职责链模式:尝试采用一系列策略模式
职责链(Chain of Responsibility)模式也许被看做一个使用策略对象的“递归的动态一般化”。此时提出一个调用,在一个链序列中的每个策略都试图满足这个调用。这个过程直到有一个策略成功满足该调用或者到达链序列的末尾才结束。在递归方法中,有个函数反复调用其自身直至达到某个终止条件;在职责链中,一个函数调用自身,(通过遍历策略链)调用函数的一个不同实现,如此反复直至达到某个终止条件。这个终止条件或者是已到达策略链的底部(这样就会返回一个默认对象;不管能否提供这个默认结果,必须有个方法能够决定该职责链搜索是成功还是失败)或者是成功找到一个策略。
除了调用一个函数来满足某个请求以外,链中的多个函数都有此机会满足某个请求,因此它有点专家系统的意味。由于职责链实际上就是一个链表,它能够动态创建,因此它可以看做是一个更一般的动态构建的switch语句。
在GoF中,有很多关于如何将职责链模式创建为一个链表的讨论。然而,如果审视这类模式,实在没必要考虑链是如何创建的;这是一个实现的细节。由于GoF是在大多数C++编译器中STL容器可利用之前编写的,它讨论创建链表最可能的原因有:(1)编译器中没有内置的链表,因此必须自己创建;(2)数据结构常常是作为学术界的一门基本的技术进行教授,GoF的作者们还没有数据结构应该是编程语言提供的有效标准工具的概念。讨论如何使用容器来实现职责链作为链的细节(在GoF中,它就是一个链表)对于这里的问题的解决没有什么意义,可以很方便地用STL容器来实现,如下所示。
在这里可以看到,使用一种自动递归搜索链中每个策略的机制,职责链模式自动找到一个解决方法:
注意,“语境”类Gimme和所有策略类都派生自同一个基类GimmeStrategy。
如果读者研读GoF中关于职责链的那部分内容,将会发现其结构与上面介绍的内容有明显不一致地方,因为他们专注于创建自己的链表。然而,如果牢记职责链的本质是尝试多个解决方法直到找到一个起作用的方法,读者就会了解按顺序排好的实现机制并不是该模式的本质所在。