职责链(Chain of Responsibility)模式:在提出一个请求时,一个链序列中的每个策略都试图满足这个请求。这个过程直到有一个策略成功满足该调用或者到达链序列的末尾才结束。
除了调用一个函数来满足某个请求外,链中的多个函数都有机会满足这个请求,因此它有点专家系统的意味。由于职责链实际上就是一个链表,它能够动态创建,因此它可以看做是一个更一般的动态构建的switch语句。
在这里可以看到,使用一种自动递归搜索链中每个策略的机制,职责链模式自动找到一个解决方法。
#include <iostream> #include <vector> //#include "../purge.h" using namespace std; enum Answer { NO, YES }; class GimmeStrategy { public: virtual Answer canIHave() = 0; virtual ~GimmeStrategy() {} }; class AskMom : public GimmeStrategy { public: Answer canIHave() { cout << "Mooom? Can I have this?" << endl; return NO; } }; class AskDad : public GimmeStrategy { public: Answer canIHave() { cout << "Dad, I really need this!" << endl; return NO; } }; class AskGrandpa : public GimmeStrategy { public: Answer canIHave() { cout << "Grandpa, is it my birthday yet?" << endl; return NO; } }; class AskGrandma : public GimmeStrategy { public: Answer canIHave() { cout << "Grandma, I really love you!" << endl; return YES; } }; class Gimme : public GimmeStrategy { vector<GimmeStrategy*> chain; public: Gimme() { chain.push_back(new AskMom()); chain.push_back(new AskDad()); chain.push_back(new AskGrandpa()); chain.push_back(new AskGrandma()); } Answer canIHave() { vector<GimmeStrategy*>::iterator it = chain.begin(); while(it != chain.end()) if((*it++)->canIHave() == YES) return YES; // Reached end without success... cout << "Whiiiiinnne!" << endl; return NO; } ~Gimme() { /* purge(chain); */ } }; int main() { Gimme chain; chain.canIHave(); }
注意,“语境”类Gimme和所有策略类都派生自同一个基类GimmeStrategy。
另外,职责链的本质是尝试多个解决方案直到找到一个起作用的方法,所以将解决方案按顺序排好的实现机制并不是该模式的本质所在。
选自《C++编程思想》。