状态模式 State -- 学习HeadFirst设计模式记录

 

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

 

面向过程方法:针对动作,在处理时switch/if-else各个状态,然后分别处理:

#include <iostream>

class GumballMachine
{
public:
    GumballMachine()
    {
        _count =  100;
        _state = NO_QUARTER;
    }

     /* 执行一个动作时,switch/if-else处理所有的状态 */
     void InsertQuarter()
    {
         switch (_state)
        {
         case SOLD_OUT:
            std::cout<< " You can't insert a quarter, the machine has sold out. "<<std::endl;
             break;

         case NO_QUARTER:
            std::cout<< " 接受投币 "<<std::endl;
            std::cout<< " You inserted a quarter. "<<std::endl;
             break;

         case HAS_QUARTER:
            std::cout<< " You can't insert another quarter. "<<std::endl;
             break;

         case SOLD:
            std::cout<< " Please wait, we're already giving you a gumball "<<std::endl;
             break;

         default:
             break;
        }
    }

     void EjectQuarter() {}
     void TurnCrank() {}
     void Dispense() {}

private:
     enum MACHINE_STATE
    {
        SOLD_OUT =  0,
        NO_QUARTER,
        HAS_QUARTER,
        SOLD,
    } ;

    MACHINE_STATE _state;
     int _count;
};

int main()
{
    std::cout<< " State Patten. "<<std::endl;

    GumballMachine gumballMachine;
    gumballMachine.InsertQuarter();

     return  0;
}

 

面向对象方法:使用状态模式,将各个状态封装为类,每个类支持所有动作。使用时,将动作委托给状态类处理。

 .h

/* 状态模式的状态接口 */
class State
{

public:
     virtual  void InsertQuarter() =  0;
     virtual  void EjectQuarter() =  0;
     virtual  void TurnCrank() =  0//  转动曲柄
     virtual  void Dispense() =  0;   //  分发
};

class GumballMachine
{
public:
    GumballMachine();
    
     void InsertQuarter();
    
     void SetState(State *state);
    State *GetNoQuarterState();
    State *GetHasQuarterState();
    
private:
    State *_noQuarterState;
    State *_hasQuarterState;
    
    State *_state;
     int _count;
};

 

 .c

#include <iostream>
#include  " main.h "
/*各个状态类*/
class NoQuarterState : public State
{
public:
    NoQuarterState(GumballMachine *pMachine) : _pGumballMachine(pMachine)
    {}

     virtual  void InsertQuarter()
    {
        std::cout<< " 接受投币 "<<std::endl;
        std::cout<< " You inserted a quarter. "<<std::endl;
         //   切换状态
        _pGumballMachine->SetState(_pGumballMachine->GetHasQuarterState());
    }
     virtual  void EjectQuarter()
    {
        std::cout<< " Invalid Action. "<<std::endl;
    }
     virtual  void TurnCrank()
    {
        std::cout<< " Invalid Action. "<<std::endl;
    }
     virtual  void Dispense()
    {
        std::cout<< " Invalid Action. "<<std::endl;
    }
private:
    GumballMachine *_pGumballMachine;
};

class QuarterState : public State
{
public:
    QuarterState(GumballMachine *pMachine) : _pGumballMachine(pMachine)
    {}

     virtual  void InsertQuarter()
    {
        std::cout<< " Invalid Action. "<<std::endl;
    }
     virtual  void EjectQuarter()
    {
        std::cout<< " Quarter Returned. "<<std::endl;
         //   切换状态
        _pGumballMachine->SetState(_pGumballMachine->GetNoQuarterState());
    }
     virtual  void TurnCrank()
    {
        std::cout<< " Crank Truned. "<<std::endl;
         //   切换状态 ...
        _pGumballMachine->SetState(_pGumballMachine->GetNoQuarterState());
    }
     virtual  void Dispense()
    {
        std::cout<< " Invalid Action. "<<std::endl;
    }

private:
    GumballMachine *_pGumballMachine;
};
// class SoldState : public State
// class SoldOutState : public State


GumballMachine::GumballMachine()
{
    _noQuarterState  =  new NoQuarterState( this);
    _hasQuarterState =  new QuarterState( this);
    _count =  100;
    _state = _noQuarterState;
}
/* 执行一个动作时,委托给状态类处理 */
void GumballMachine::InsertQuarter()
{
    _state->InsertQuarter();
}
void GumballMachine::SetState(State *state)
{
    _state = state;
}
State *GumballMachine::GetNoQuarterState()
{
     return _noQuarterState;
}
State *GumballMachine::GetHasQuarterState()
{
     return _hasQuarterState;
}


int main()
{
    std::cout<< " State Patten. "<<std::endl;
    
    GumballMachine gumballMachine;
    gumballMachine.InsertQuarter();
    
     return  0;
}   

 

你可能感兴趣的:(first)