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 对象的引用.

posted @ 2013-02-06 11:06  walfud  阅读(174)  评论(0编辑  收藏  举报