您的位置:首页 > 编程语言 > C语言/C++

设计模式系列6-----C++实现状态模式(State Pattern)

2011-12-09 19:52 911 查看

什么是状态模式?

      Definition: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

      当对象有几种状态时,不同状态时有不同的表现,为了避免复杂的ifelse逻辑,将每个状态的逻辑单独封装在自己的实现中,容易写出逻辑清晰的代码。

 

类图结构:



      其实上图和策略模式的类图基本一致,那他们的差别在哪里呢?其实主要是应用的目的不一样:策略模式主要针对对象的某一种behavior有多种可能实现,而状态模式是当对象的状态有多种,每种状态下有不同表现,基本上状态模式封装的是一组behavior。

 

Example:

      例子模拟游戏中的一种坦克,有两种状态:坦克状态(Tank),能移动,攻击为20;架起状态(Siege),无法移动,攻击力增强为100。

state.h如下:

class SiegeTank;

class ISiegeTankState
{
public:
virtual void move(int x, int y) = 0;
virtual void attack() = 0;
};

class SiegeState : public ISiegeTankState
{
public:
SiegeState(SiegeTank* pTank);

virtual void move(int x, int y);

virtual void attack();

private:
SiegeTank* m_pTank;
};

class TankState : public ISiegeTankState
{
public:
TankState(SiegeTank* pTank);

virtual void move(int x, int y);

virtual void attack();

private:
SiegeTank* m_pTank;
};


 

state.cpp如下:

#include "tank.h"
#include "state.h"
#include <iostream>

SiegeState::SiegeState( SiegeTank* pTank ) : m_pTank(pTank)
{

}

void SiegeState::move( int x, int y )
{
std::cout << "Can't move in siege mode." << std::endl;
}

void SiegeState::attack()
{
std::cout << "Attacking for 100" << std::endl;
}

TankState::TankState( SiegeTank* pTank ) : m_pTank(pTank)
{

}

void TankState::move( int x, int y )
{
std::cout << "Move to (" << x << ", " << y << ")" << std::endl;
}

void TankState::attack()
{
std::cout << "Attacking for 20" << std::endl;
}


 

tank.h如下:

#ifndef __TANK_H__
#define __TANK_H__

class TankState;
class SiegeState;
class ISiegeTankState;

class SiegeTank
{
public:
SiegeTank();

void enterTankMode();
void enterSiegeMode();

public:
void attack();
void move(int x, int y);

private:
void setState(ISiegeTankState* pSiegeTankMode);

private:
TankState* m_pTankState;
SiegeState* m_pSiegeState;
ISiegeTankState* m_pSiegeTankState;
};
#endif


 

tank.cpp如下:

#include "tank.h"
#include "state.h"
#include <iostream>

SiegeTank::SiegeTank()
{
m_pTankState = new TankState(this);
m_pSiegeState = new SiegeState(this);
m_pSiegeTankState = m_pTankState;
}

void SiegeTank::setState( ISiegeTankState* pSiegeTankMode )
{
m_pSiegeTankState = pSiegeTankMode;
}

void SiegeTank::move( int x, int y )
{
m_pSiegeTankState->move(x, y);
}

void SiegeTank::attack()
{
m_pSiegeTankState->attack();
}

void SiegeTank::enterTankMode()
{
m_pSiegeTankState = m_pTankState;
std::cout << "Switch to tank mode" << std::endl;
}

void SiegeTank::enterSiegeMode()
{
m_pSiegeTankState = m_pSiegeState;
std::cout << "Switch to siege mode" << std::endl;
}


 

测试代码main.cpp如下:

#include "tank.h"
#include "state.h"

int main()
{
SiegeTank tank;

tank.enterTankMode();
tank.attack();
tank.move(1, 1);

tank.enterSiegeMode();
tank.attack();
tank.move(2, 2);

tank.enterTankMode();
tank.attack();
tank.move(3, 3);

return 0;
}


 

运行结果如下:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: