Design Pattern --- State
class State { public: // Interface. virtual void foo() = 0; virtual void bar() = 0; }; class StateVer0 : public State { public: // Interface. virtual void foo() override { cout <<"verion 0: foo." <<endl; } virtual void bar() override { cout <<"verion 0: bar." <<endl; } }; class StateVer1 : public State { public: // Interface. virtual void foo() override { cout <<"verion 1: foo." <<endl; } virtual void bar() override { cout <<"verion 1: bar." <<endl; } }; class StateVer2 : public State { public: // Interface. virtual void foo() override { cout <<"verion 2: foo." <<endl; } virtual void bar() override { cout <<"verion 2: bar." <<endl; } }; class StateVerUnknown : public State { public: // Interface. virtual void foo() override { cout <<"unknown verion: foo." <<endl; } virtual void bar() override { cout <<"unknown verion: bar." <<endl; } }; class Context { State *m_handle; public: Context(int ver) : m_handle(nullptr) { switch (ver) { case 0: m_handle = new StateVer0; break; case 1: m_handle = new StateVer1; break; case 2: m_handle = new StateVer2; break; // case ...: // m_handle = new StateVerX; // break; default: m_handle = new StateVerUnknown; break; }//switch } ~Context() { delete m_handle; } public: // Interface. void foo() { //// Unmaintainable! //switch (m_ver) //{ //case 0: // cout <<"verion 0: foo." <<endl; // break; //case 1: // cout <<"verion 1: foo." <<endl; // break; //case 2: // cout <<"verion 2: foo." <<endl; // break; //// case ...: //// cout <<"verion x: foo." <<endl; //// break; //default: // cout <<"unknown verion: foo." <<endl; // break; //}//switch m_handle->foo(); } void bar() { //// Unmaintainable! //switch (m_ver) //{ //case 0: // cout <<"verion 0: bar." <<endl; // break; //case 1: // cout <<"verion 1: bar." <<endl; // break; //case 2: // cout <<"verion 2: bar." <<endl; // break; //// case ...: //// cout <<"verion x: bar." <<endl; //// break; //default: // cout <<"unknown verion: bar." <<endl; // break; //}//switch m_handle->bar(); } }; int main() { Context c(2); c.foo(); c.bar(); return 0; }
State 模式极大地避免了在一个类中, 每个函数都有一个很大的 switch 语句.
此模式的核心就是将这些 switch 中的不同 case 抽象出来, 放到一个 class 中集中管理, 这样代码的可维护性大大增加.
State 在必要的时候可能需要持有 Context 的引用, 此时可在 State 的构造函数中传入 Context 对象的引用.