State 모드 (상태 모드) 학습

12947 단어 디자인 모드
간단 한 십자 전문 상태 기 를 통 해 한 걸음 한 걸음 간단 한 디자인 에서 디자인 원칙 과 디자인 모델 을 활용 하 는 실현 까지.코드 는 한 걸음 한 걸음 추상 / 재 구성 되 고 주석 에서 모든 추상 과 재 구성 의 미 를 상세 하 게 설명 했다.코드 는 복사 하여 완전 하 게 실행 할 수 있다.
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;

typedef enum
{
    LOCKED,
    UNLOCKED,
}State;

typedef enum
{
    COIN,
    PASS
}Event;

#if 0 //    ,   ,switch/case      ,          Action
class Turnstile
{
public:
    int state = LOCKED;
    void HandleEvent(Event event)
    {
        switch (state)
        {
        case LOCKED:
            switch (event)
            {
            case COIN:
                cout << "lock (event:coin)-> unlock" << endl;
                state = UNLOCKED;
                break;
            case PASS:
                cout << "Pass when locked, alarm!" << endl;
                //state not change
                break;
            default:
                break;
            }
            break;
        case UNLOCKED:
            switch (event)
            {
            case COIN:
                cout << "unlock (event:coin)-> unlock" << endl;
                //state not change
                break;
            case PASS:
                cout << "unlock (event:pass)-> lock" << endl;
                state = LOCKED;
                break;
            default:
                break;
            }
            break;
        default:
            break;
        }
    }
};

int main(int argc, char** argv)
{
    Turnstile turnstile;
    turnstile.state = LOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
    turnstile.state = UNLOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
}
#endif

#if 0//     ,             ,Action    。        Action ,      ,        。       Action     OCP,              OCP
class AbstractTurnstile
{
public:
    int state = LOCKED;
    virtual void Unlock() = 0;
    virtual void Lock() = 0;
    virtual void Alarm() = 0;
    virtual void ThankYou() = 0;
    void HandleEvent(Event event)
    {
        switch (state)
        {
        case LOCKED:
            switch (event)
            {
            case COIN:
                Unlock();
                state = UNLOCKED;
                break;
            case PASS:
                Alarm();
                //state not change
                break;
            default:
                break;
            }
            break;
        case UNLOCKED:
            switch (event)
            {
            case COIN:
                ThankYou();
                //state not change
                break;
            case PASS:
                Lock();
                state = LOCKED;
                break;
            default:
                break;
            }
            break;
        default:
            break;
        }
    }
};

class ACustomerTurnstile : public AbstractTurnstile
{
    virtual void Unlock() { cout << "lock (event:coin)-> unlock" << endl; }
    virtual void Lock() { cout << "unlock (event:pass)-> lock" << endl; }
    virtual void Alarm() { cout << "Pass when locked, alarm!" << endl; }
    virtual void ThankYou() { cout << "unlock (event:coin)-> unlock" << endl; }
};

int main(int argc, char** argv)
{
    AbstractTurnstile *pTurnstile = new ACustomerTurnstile;
    pTurnstile->state = LOCKED;
    pTurnstile->HandleEvent(PASS);
    assert(pTurnstile->state == LOCKED);
    pTurnstile->state = UNLOCKED;
    pTurnstile->HandleEvent(PASS);
    assert(pTurnstile->state == LOCKED);
    delete pTurnstile;
}
#endif

#if 0//       :        ,   Action     TurnstileAction  ,        Turnstile  ,        。
//    (main  )       TurnstileAction        
class TurnstileAction
{
public:
    virtual void Unlock() = 0;
    virtual void Lock() = 0;
    virtual void Alarm() = 0;
    virtual void ThankYou() = 0;
};
class Turnstile
{
public:
    int state = LOCKED;
    TurnstileAction* pAction = NULL;
    Turnstile(TurnstileAction* pAct)
    {
        pAction = pAct;
    }
    void HandleEvent(Event event)
    {
        switch (state)
        {
        case LOCKED:
            switch (event)
            {
            case COIN:
                pAction->Unlock();
                state = UNLOCKED;
                break;
            case PASS:
                pAction->Alarm();
                //state not change
                break;
            default:
                break;
            }
            break;
        case UNLOCKED:
            switch (event)
            {
            case COIN:
                pAction->ThankYou();
                //state not change
                break;
            case PASS:
                pAction->Lock();
                state = LOCKED;
                break;
            default:
                break;
            }
            break;
        default:
            break;
        }
    }
};

int main(int argc, char** argv)
{
    //           Action
    class ACustomerAction : public TurnstileAction
    {
        virtual void Unlock() { cout << "lock (event:coin)-> unlock" << endl; }
        virtual void Lock() { cout << "unlock (event:pass)-> lock" << endl; }
        virtual void Alarm() { cout << "Pass when locked, alarm!" << endl; }
        virtual void ThankYou() { cout << "unlock (event:coin)-> unlock" << endl; }
    };
    //  Action  Turnstile   
    ACustomerAction action;
    Turnstile turnstile(&action);
    //  Turnstile
    turnstile.state = LOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
    turnstile.state = UNLOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
}
#endif

#if 0//     ,        ,                     TurnstileAction  ,          ,  OCP
/*//     :  Turnstile                  
typedef void(*Action)();
class TurnstileAction
{
public:
    static void Unlock() { cout << "lock (event:coin)-> unlock" << endl; }
    static void Lock() { cout << "unlock (event:pass)-> lock" << endl; }
    static void Alarm() { cout << "Pass when locked, alarm!" << endl; }
    static void ThankYou() { cout << "unlock (event:coin)-> unlock" << endl; }
};
class Transition
{
public:
    Transition(int inCurrentState, int inEvent, int inNewState, Action inAction) :
        currentState(inCurrentState), event(inEvent), newState(inNewState), action(inAction)
    {;}
    int currentState;
    int event;
    int newState;
    Action action;
};
class Turnstile
{
public:
    int state = LOCKED;
    vector<Transition> trans;
    Turnstile()
    {
        //           :    ,  ,   ,  
        AddTransition(LOCKED, COIN, UNLOCKED, TurnstileAction::Unlock);
        AddTransition(LOCKED, PASS, LOCKED, TurnstileAction::Alarm);
        AddTransition(UNLOCKED, COIN, UNLOCKED, TurnstileAction::ThankYou);
        AddTransition(UNLOCKED, PASS, LOCKED, TurnstileAction::Lock);
    }
    void HandleEvent(Event event)
    {
        for (unsigned int i = 0; i < trans.size(); i++)
        {
            Transition* pTrans = &(trans[i]);
            if (state == pTrans->currentState && event == pTrans->event)
            {
                state = pTrans->newState;
                pTrans->action();
            }
        }
    }
private:
    void AddTransition(int currentState, int event, int newState, Action action)
    {
        trans.push_back(Transition(currentState, event, newState, action));
    }
};
*/

//  :              ,     (     ,Action     )         
//  ,     
typedef void(*Action)();
class Transition
{
public:
    Transition(int inCurrentState, int inEvent, int inNewState, Action inAction) :
        currentState(inCurrentState), event(inEvent), newState(inNewState), action(inAction)
    { ; }
    int currentState;
    int event;
    int newState;
    Action action;
};
class StateMachine
{
public:
    int state;
    vector<Transition> trans;
    void HandleEvent(Event event)
    {
        for (unsigned int i = 0; i < trans.size(); i++)
        {
            Transition* pTrans = &(trans[i]);
            if (state == pTrans->currentState && event == pTrans->event)
            {
                state = pTrans->newState;
                pTrans->action();
            }
        }
    }
protected:
    void AddTransition(int currentState, int event, int newState, Action action)
    {
        trans.push_back(Transition(currentState, event, newState, action));
    }
};

//  ,       
class Turnstile : public StateMachine
{
public:
    //  Action     
    static void Unlock() { cout << "lock (event:coin)-> unlock" << endl; }
    static void Lock() { cout << "unlock (event:pass)-> lock" << endl; }
    static void Alarm() { cout << "Pass when locked, alarm!" << endl; }
    static void ThankYou() { cout << "unlock (event:coin)-> unlock" << endl; }
    //        
    Turnstile()
    {
        //           :    ,  ,   ,  
        AddTransition(LOCKED, COIN, UNLOCKED, Unlock);
        AddTransition(LOCKED, PASS, LOCKED, Alarm);
        AddTransition(UNLOCKED, COIN, UNLOCKED, ThankYou);
        AddTransition(UNLOCKED, PASS, LOCKED, Lock);
    }
};

int main(int argc, char** argv)
{
    //  Action  Turnstile   
    Turnstile turnstile;
    //  Turnstile
    turnstile.state = LOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
    turnstile.state = UNLOCKED;
    turnstile.HandleEvent(PASS);
    assert(turnstile.state == LOCKED);
}
#endif

#if 1/*      ,    ,                           ,              。
             :1.      ,2.    ,            ,        (State  ,  State ,Turnstile ),      /  /  
                   2      ,STATE       ,              。
            ,STATE   C++          !Turnstile TurnstileLockedState       ,      。             ,
                   http://zhidao.baidu.com/link?url=5jzADbx87CLFt_NihyAO79FwIFGFwDWW5VZsOgH-AU77ZdC-Hga5PgVlVkJiu7aVigim3LSuZ9EdSiTCB2Ul1_
               http://www.cnblogs.com/wanggary/archive/2011/04/21/2024117.html */
class Turnstile;
class TurnstileState;
class TurnstileLockedState;
class TurnstileUnlockedState;
//    ,      ,              
class TurnstileState
{
public:
    virtual void CoinEvent(Turnstile* pTs) = 0;
    virtual void PassEvent(Turnstile* pTs) = 0;
};
//    ,                  。         ,         , Turnstile       
class TurnstileLockedState : public TurnstileState
{
public:
    virtual void CoinEvent(Turnstile* pTs);
    virtual void PassEvent(Turnstile* pTs);
};
class TurnstileUnlockedState : public TurnstileState
{
public:
    virtual void CoinEvent(Turnstile* pTs);
    virtual void PassEvent(Turnstile* pTs);
};
//Context ,                    Action
class Turnstile
{
private:
    TurnstileState* pState = NULL;
    TurnstileLockedState lockedState;
    TurnstileUnlockedState unlockedState;
public:
    Turnstile()
    {
        pState = &lockedState;
    }
    void SetState(State state)
    {//           ,        
        if (state == UNLOCKED)
        {
            pState = &unlockedState;
        }
        else
        {
            pState = &lockedState;
        }
    }
    void CoinEvent()
    {
        pState->CoinEvent(this);
    }
    void PassEvent()
    {
        pState->PassEvent(this);
    }
    //Action  ,           TurnstileAction    
    void Unlock() { cout << "lock (event:coin)-> unlock" << endl; }
    void Lock() { cout << "unlock (event:pass)-> lock" << endl; }
    void Alarm() { cout << "Pass when locked, alarm!" << endl; }
    void ThankYou() { cout << "unlock (event:coin)-> unlock" << endl; }
};

//        ,              Turnstile      
void TurnstileLockedState::CoinEvent(Turnstile* pTs)
{
    pTs->SetState(UNLOCKED);//    
    pTs->Unlock();//  Action
}
void TurnstileLockedState::PassEvent(Turnstile* pTs)
{
    //    : 
    pTs->Alarm();//  Action
}
void TurnstileUnlockedState::CoinEvent(Turnstile* pTs)
{
    //    : 
    pTs->ThankYou();//  Action
}
void TurnstileUnlockedState::PassEvent(Turnstile* pTs)
{
    pTs->SetState(LOCKED);//    
    pTs->Lock();//  Action
}

int main(int argc, char** argv)
{
    //  Action  Turnstile   
    Turnstile turnstile;
    //  Turnstile
    turnstile.SetState(LOCKED);
    turnstile.PassEvent();
    //assert(turnstile.state == LOCKED);
    turnstile.CoinEvent();//to be unlocked
    turnstile.PassEvent();//to be locked
    //assert(turnstile.state == LOCKED);
}
#endif

좋은 웹페이지 즐겨찾기