State模式的应用探讨

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


你可能感兴趣的:(State模式的应用探讨)