设计模式中的状态模式是做状态机的基础知识,用状态模式设计的状态机会非常优雅。
状态模式的本质就是把多变的状态抽象成一个接口,把控制状态的条件封装成一个控制类,利用多态性,控制类操作状态接口就可以完成对各种状态的切换。
举一个例子:
现在要设计一个尽量精简的智能小猫,小猫平时会睡觉,但遇到危险要能自动跑开。分析一下这个场景,就发现小猫有两种状态,睡觉和逃跑,控制条件就是是否有危险,这样就可以用状态模式来设计了。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;
}
这样,一个精简的智能小猫就做出来了。
浙公网安备 33010602011771号