//直接貼代碼吧,歡迎提出缺點(diǎn)及改進(jìn)方式
//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);//根據(jù)req請(qǐng)求決定采取的動(dòng)作
protected:
CScenario* _scenario;
};

class CScenario//處于的場(chǎng)景


{
public:
enum ActionType

{
AT_TELL_ON_ROAD = 0x01,
AT_TELL_IN_RIVER = 0x02,
AT_TELL_MEET_ENEMY = 0x04,
AT_TELL_INFO = 0x07,//上面三個(gè)的"組合"

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)
{}//采取的動(dòng)作

virtual void Walk()
{}//走路

virtual void Swim()
{}//游泳

virtual void Fire()
{}//開(kāi)槍
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()
{};//禁止直接定義對(duì)象
};

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;//一個(gè)字節(jié)的Action類型
if (!(action & GetScenario()->GetSupportedAction()))//不支持該Action

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


return;
}

//0.實(shí)現(xiàn)CNoOp,作為soldier的初始化狀態(tài)
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.實(shí)現(xiàn)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.實(shí)現(xiàn)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.實(shí)現(xiàn)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.遇到敵人,狀態(tài)改變
at = CScenario::AT_TELL_MEET_ENEMY;
soldier.HandleRequest((BYTE*)&at);

//3.遇到敵人后開(kāi)火
at = CScenario::AT_FIRE;
soldier.HandleRequest((BYTE*)&at);

//4.進(jìn)入河中,狀態(tài)改變
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;
}

