State模式的应用探讨
//直接贴代码吧,欢迎提出缺点及改进方式
//StatePattern.h
#ifndef STATE_PATTERN_H
#define
STATE_PATTERN_H

#include
<
iostream
>
using
namespace
std;

typedef unsigned
char
BYTE;
class
CScenario;
//
decl
class
CSoldier

{
public:
CSoldier();

~CSoldier()
{};
CScenario* GetScenario();
void ChangeScenario(CScenario* scenario);
void HandleRequest(BYTE* req);//根据req请求决定采取的动作
protected:
CScenario* _scenario;
}
;

class
CScenario
//
处于的场景

{
public:
enum ActionType

{
AT_TELL_ON_ROAD = 0x01,
AT_TELL_IN_RIVER = 0x02,
AT_TELL_MEET_ENEMY = 0x04,
AT_TELL_INFO = 0x07,//上面三个的"组合"

AT_WALK = 0x08,
AT_SWIM = 0x10,
AT_FIRE = 0x20
};
public:

virtual void ChangeScenario(CSoldier* soldier,CScenario* scenario)
{}

virtual int GetSupportedAction()
{return 0;}

virtual void act(CSoldier*soldier, ActionType at)
{}//采取的动作

virtual void Walk()
{}//走路

virtual void Swim()
{}//游泳

virtual void Fire()
{}//开枪
protected:

CScenario()
{};
}
;

class
CNoOp :
public
CScenario

{
public:

CNoOp()
{}
static CScenario* Instance();
void ChangeScenario(CSoldier* soldier,CScenario* scenario);
int GetSupportedAction();
void act(CSoldier*soldier,ActionType at);
private:
static CScenario* _instance;
}
;

class
COnRoad :
public
CScenario

{
public:
static CScenario* Instance();
void ChangeScenario(CSoldier* soldier,CScenario* scenario);
void Walk();
int GetSupportedAction();
void act(CSoldier*soldier,ActionType at);
private:
static CScenario* _instance;
protected:

COnRoad()
{};//禁止直接定义对象
}
;

class
CInRiver :
public
CScenario

{
public:
static CScenario* Instance();
void ChangeScenario(CSoldier* soldier,CScenario* scenario);
void Swim();
int GetSupportedAction();
void act(CSoldier*soldier,ActionType at);
private:
static CScenario* _instance;
protected:

CInRiver()
{};
}
;

class
CMeetEnemy :
public
CScenario

{
public:
static CScenario* Instance();
void ChangeScenario(CSoldier* soldier,CScenario* scenario);
void Fire();
int GetSupportedAction();
void act(CSoldier*soldier,ActionType at);
private:
static CScenario* _instance;
protected:

CMeetEnemy()
{};
}
;
#endif
//StatePattern.cpp
#include
"
StatePattern.h
"
CSoldier::CSoldier()

{
this->ChangeScenario(CNoOp::Instance());
}
CScenario
*
CSoldier::GetScenario()

{
return _scenario;
}
void
CSoldier::ChangeScenario(CScenario
*
scenario)

{
this->_scenario = scenario;
}
void
CSoldier::HandleRequest(BYTE
*
req)

{
if (req == NULL)

{
cout << "req == NULL" << endl;
return;
}
BYTE action = *req;//一个字节的Action类型
if (!(action & GetScenario()->GetSupportedAction()))//不支持该Action

{
cout << "不支持该操作类型" << endl;
return;
}
GetScenario()->act(this,(CScenario::ActionType)action);


return;
}

//
0.实现CNoOp,作为soldier的初始化状态
CScenario
*
CNoOp::_instance
=
NULL;
CScenario
*
CNoOp::Instance()

{
if (_instance == NULL)

{
_instance = new CNoOp();
}
return _instance;
}
void
CNoOp::ChangeScenario(CSoldier
*
soldier,CScenario
*
scenario)

{
soldier->ChangeScenario(scenario);
return;
}
int
CNoOp::GetSupportedAction()

{
return AT_TELL_INFO;
}
void
CNoOp::act(CSoldier
*
soldier,ActionType at)

{
switch(at)

{
case AT_TELL_ON_ROAD:
cout << "---> on road" << endl;
soldier->ChangeScenario(COnRoad::Instance());
break;
case AT_TELL_IN_RIVER:
cout << "---> in river" << endl;
soldier->ChangeScenario(CInRiver::Instance());
break;
case AT_TELL_MEET_ENEMY:
cout << "---> meet enymy" << endl;
soldier->ChangeScenario(CMeetEnemy::Instance());
break;
default:
cout << "unkown action type" << endl;
break;
}
return;
}

//
1.实现COnRoad
CScenario
*
COnRoad::_instance
=
NULL;
CScenario
*
COnRoad::Instance()

{
if (_instance == NULL)

{
_instance = new COnRoad();
}
return _instance;
}
void
COnRoad::Walk()

{
cout << "walk" << endl;
return;
}
int
COnRoad::GetSupportedAction()

{
return AT_TELL_INFO | AT_WALK;
}
void
COnRoad::ChangeScenario(CSoldier
*
soldier,CScenario
*
scenario)

{
soldier->ChangeScenario(scenario);
return;
}
void
COnRoad::act(CSoldier
*
soldier,ActionType at)

{
switch(at)

{
case AT_TELL_ON_ROAD:
cout << "on road ---> on road" << endl;
break;
case AT_TELL_IN_RIVER:
cout << "on road ---> in river" << endl;
soldier->ChangeScenario(CInRiver::Instance());
break;
case AT_TELL_MEET_ENEMY:
cout << "on road ---> meets enymy" << endl;
soldier->ChangeScenario(CMeetEnemy::Instance());
break;
case AT_WALK:
cout << "on road : walk now" << endl;
break;
default:
cout << "unkown action type" << endl;
break;
}
return;
}

//
2.实现CInRiver
CScenario
*
CInRiver::_instance
=
NULL;
CScenario
*
CInRiver::Instance()

{
if (_instance == NULL)

{
_instance = new CInRiver();
}
return _instance;
}
void
CInRiver::Swim()

{
cout << "swim" << endl;
return;
}
int
CInRiver::GetSupportedAction()

{
return AT_TELL_INFO | AT_SWIM;
}
void
CInRiver::ChangeScenario(CSoldier
*
soldier,CScenario
*
scenario)

{
soldier->ChangeScenario(scenario);
return;
}
void
CInRiver::act(CSoldier
*
soldier,ActionType at)

{
switch(at)

{
case AT_TELL_ON_ROAD:
cout << "in river ---> on road" << endl;
soldier->ChangeScenario(COnRoad::Instance());
break;
case AT_TELL_IN_RIVER:
cout << "in river ---> in river" << endl;
break;
case AT_TELL_MEET_ENEMY:
cout << "in river : meets enymy" << endl;
soldier->ChangeScenario(CMeetEnemy::Instance());
break;
case AT_SWIM:
cout << "in river : swim now" << endl;
break;
default:
cout << "unkown action type" << endl;
break;
}
return;
}

//
3.实现CMeetEnemy
CScenario
*
CMeetEnemy::_instance
=
NULL;
CScenario
*
CMeetEnemy::Instance()

{
if (_instance == NULL)

{
_instance = new CMeetEnemy();
}
return _instance;
}
void
CMeetEnemy::Fire()

{
cout << "fire" << endl;
return;
}
int
CMeetEnemy::GetSupportedAction()

{
return AT_TELL_INFO | AT_FIRE;
}
void
CMeetEnemy::ChangeScenario(CSoldier
*
soldier,CScenario
*
scenario)

{
soldier->ChangeScenario(scenario);
return;
}
void
CMeetEnemy::act(CSoldier
*
soldier,ActionType at)

{
switch(at)

{
case AT_TELL_ON_ROAD:
cout << "meet enemy ---> on road" << endl;
soldier->ChangeScenario(COnRoad::Instance());
break;
case AT_TELL_IN_RIVER:
cout << "meet enemy ---> in river" << endl;
soldier->ChangeScenario(CInRiver::Instance());
break;
case AT_TELL_MEET_ENEMY:
cout << "meet enemy ---> meet enymy" << endl;
break;
case AT_FIRE:
cout << "meet enemy : fire now" << endl;
break;
default:
cout << "unkown action type" << endl;
break;
}
return;
}
//StatePatternTest.cpp
//
StateMachine.cpp : Defines the entry point for the console application.
//
#include
<
windows.h
>
#include
"
StatePattern.h
"

int
main(
int
argc,
char
*
argv[])

{
typedef CScenario::ActionType ActionType;
ActionType at;
CSoldier soldier;

//0.在陆地上
at = CScenario::AT_TELL_ON_ROAD;
soldier.HandleRequest((BYTE*)&at);

//1.陆地上行走
at = CScenario::AT_WALK;
soldier.HandleRequest((BYTE*)&at);
//2.遇到敌人,状态改变
at = CScenario::AT_TELL_MEET_ENEMY;
soldier.HandleRequest((BYTE*)&at);

//3.遇到敌人后开火
at = CScenario::AT_FIRE;
soldier.HandleRequest((BYTE*)&at);

//4.进入河中,状态改变
at = CScenario::AT_TELL_IN_RIVER;
soldier.HandleRequest((BYTE*)&at);

//5.河中游泳
at = CScenario::AT_SWIM;
soldier.HandleRequest((BYTE*)&at);

//5.清理分配资源
delete CNoOp::Instance();
delete COnRoad::Instance();
delete CInRiver::Instance();
delete CMeetEnemy::Instance();

system("pause");
return 0;
}

//StatePattern.h










































































































































//StatePattern.cpp































































































































































































































































































//StatePatternTest.cpp
















































