状态模式产生一个可以改变其类的对象,当发现大多数或者所有函数中都存在有条件的代码时,这种模式很有用。和代理模式一样,这种模式通过一个前端对象来使后端实例对象履行其职责。然而,在前端对象生存其间,状态模式从一个实现对象到另一个实现对象进行切换,以实现对于相同函数调用产生不同的行为。
例如,在青蛙王子童话中,青蛙王子依照其所处的状态而有不同的行为。先通过测试一个bool变量来实现:
// KissingPrincess #include <iostream> using namespace std; class Creature { bool isFrog; public: Creature() : isFrog(true) {} void greet() { if(isFrog) cout << "Ribbet!" << endl; else cout << "Darling!" << endl; } void kiss() { isFrog = false; } }; int main() { Creature creature; creature.greet(); creature.kiss(); creature.greet(); }
然而,greet()函数,可能还会有其它函数在执行操作前都必须测试变量isFrog,就样就使代码变得笨拙至极,特别是在系统中加入额外的状态时情况会更加严重。通过将操作委派给状态对象,这种情况就可以改变,代码从而得到了简化。
#include <iostream> #include <string> using namespace std; class Creature { class State { public: virtual string response() = 0; }; class Frog : public State { public: string response() { return "Ribbet!"; } }; class Prince : public State { public: string response() { return "Darling!"; } }; State* state; public: Creature() : state(new Frog()) {} void greet() { cout << state->response() << endl; } void kiss() { delete state; state = new Prince(); } }; int main() { Creature creature; creature.greet(); creature.kiss(); creature.greet(); }
选自《C++编程思想》。