网络服务器软件开发/中间件开发,关注ACE/ICE/boost

C++博客 首页 新随笔 联系 聚合 管理
  152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks
//直接贴代码吧,欢迎提出缺点及改进方式
//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;
}


posted on 2008-05-26 12:46 true 阅读(1545) 评论(1)  编辑 收藏 引用 所属分类: Design Pattern

Feedback

# re: State模式的应用探讨[未登录] 2008-05-26 22:14 steven
不错,受益了  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理