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
//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;
}
//
#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;
}