设计模式中的状态模式是做状态机的基础知识,用状态模式设计的状态机会非常优雅。

    状态模式的本质就是把多变的状态抽象成一个接口,把控制状态的条件封装成一个控制类,利用多态性,控制类操作状态接口就可以完成对各种状态的切换。

举一个例子:
     现在要设计一个尽量精简的智能小猫,小猫平时会睡觉,但遇到危险要能自动跑开。分析一下这个场景,就发现小猫有两种状态,睡觉和逃跑,控制条件就是是否有危险,这样就可以用状态模式来设计了。UML图如下:

 

 

    首先设计出抽象的状态父类,有一个纯虚函数virtualvoidexecute(CTroll* troll),子类必须继承,然后逃跑类和睡觉类继承状态类。代码如下:

#pragmaonce

#include "Troll.h"

classCTroll;

 

classCState

{

public:

       CState(void);

       ~CState(void);

       virtualvoidexecute(CTroll* troll)=0;

};

 

classCState_Runaway:publicCState

{

private:

       voidRun(){cout<<"I will run away!"<<endl;}

public:   

       voidexecute(CTroll* troll);

};

 

classCState_Sleep:publicCState

{

private:

       voidSleep(){cout<<"sleep ZZZZZZZZZZZ"<<endl;}

public:

       voidexecute(CTroll* troll);

};

    再设计控制类,控制类的核心就是有一个状态类的指针,这个指针指向状态类的父类,这样利用多态性,就可以操作各状态子类了。代码如下:

#pragmaonce

#include "stdafx.h"

#include "State.h"

classCState;

 

 

classCTroll

{

private:

       CState*   m_pCurrentState;

       bool      m_bSafe;

public:

       CTroll(void);

       ~CTroll(void);

public:

       voidUpdate();

       voidChageState(CState* pNewState);

       voidSetSafe(bool safe){m_bSafe=safe;}

       boolGetSafe(){returnm_bSafe;}

};

   状态类的实现如下:

#include "State.h"

#include "stdafx.h"

 

CState::CState(void)

{

}

 

 

CState::~CState(void)

{

}

 

 

 

 

 

voidCState_Runaway::execute(CTroll* troll)

{

       if(troll->GetSafe())

       {

              troll->ChageState(newCState_Sleep());

       }

       else

       {

              Run();

       }

}

 

voidCState_Sleep::execute(CTroll* troll)

{

       if(troll->GetSafe())

       {

              Sleep();

       }

       else

       {

              troll->ChageState(newCState_Runaway());

             

       }

}

 

控制类的实现如下:

#include "Troll.h"

 

 

CTroll::CTroll(void)

{

       m_pCurrentState=newCState_Sleep();

       m_bSafe=true;

}

 

 

CTroll::~CTroll(void)

{

       deletem_pCurrentState;

}

 

voidCTroll::Update()

{

       m_pCurrentState->execute(this);

}

voidCTroll::ChageState(CState* pNewState)

{

       deletem_pCurrentState;

       m_pCurrentState=pNewState;

       Update();

}

 

最后是主程序:

#include "stdafx.h"

#include "State.h"

intmain()

{

       CTroll cat;

       cat.Update();

       bool safe=false;

       cat.SetSafe(safe);

       cat.Update();

       system("pause");

       return0;

}

这样,一个精简的智能小猫就做出来了。