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

状态模式(state)C++实现

2016-04-06 20:30 465 查看

状态模式

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

将与特点状态相关的行为局部化,并且将不同状态的行为分割开来!

UML:

  


代码实现:

  以前很喜欢玩war3里面的国家对抗,是一个建造类游戏。里面的建筑在不同的时候有不同的状态,例如兵营在产兵的时候会发白光,

受伤的时候会着火,建造的时候有建筑特效。兵营在建造没完成的时候不能升级和产兵,升级的时候不能产兵,受伤着火了也能继续产兵或升级。

假设这些建筑的状态和表现为:建造-建造特效、受伤-受伤着火、升级-升级蓝光、生成-生产白光、修复-修复绿光。

实现各种状态代码state.h:

#ifndef STATE_H
#define STATE_H
#include <iostream>
using namespace std;

class absState{
public:
virtual void show() = 0;
};

class buildingState:public absState{
public:
virtual void show()
{
cout<<"建造特效  ";
}
};

class fireState:public absState{
public:
virtual void show()
{
cout<<"受伤着火  ";
}
};

class productionState:public absState{
public:
virtual void show()
{
cout<<"生产白光  ";
}
};

class upGradeState:public absState
{
public:
virtual void show()
{
cout<<"升级蓝光  ";
}
};

class repairState:public absState
{
public:
virtual void show()
{
cout<<"修复绿光  ";
}
};
#endif


建筑实现代码building.h:

#ifndef BUILDING_H
#define BUILDING_H
#include "state.h"

#include <map>
#include <iostream>
using namespace std;

enum StateType
{
BUILDING, INJURED, REPAIR, UPGRADE, PRODUCTION
};

class absBuilding
{
public:
absBuilding(char* name):mName(name){}
virtual void show()
{
cout<<mName<<"表现:"<<endl;
map<StateType, absState*>::iterator beg = mStates.begin();
for ( ; beg != mStates.end(); beg++)
{
beg->second->show();
}
cout<<endl;
};
void eraseState(StateType type)  //实现删除一个特效
{
auto result = mStates.find(type);
if(result != mStates.end())
mStates.erase(result);
}
protected:
char* mName;
map<StateType, absState*> mStates;
};

class concreteBuilding:public absBuilding
{
public:
concreteBuilding(char* name):absBuilding(name)
{
mStates[BUILDING] = new buildingState();
}
void upGrade()
{
auto result = mStates.find(UPGRADE);
if(result == mStates.end())
{
mStates[UPGRADE] = new upGradeState();
}
eraseState(BUILDING);    //升级的时候必须是建造过程已经结束,所以需要删掉“建筑”状态
eraseState(PRODUCTION);   //升级的时候不能进行生产
}
void production()
{
auto result = mStates.find(PRODUCTION);
if(result == mStates.end())
{
mStates[PRODUCTION] = new upGradeState();
}
eraseState(BUILDING);  //生产的时候必须已经建造完成
eraseState(UPGRADE);   //生产的时候不能升级
}
void injured()
{
auto result = mStates.find(INJURED);
if(result == mStates.end())
{
mStates[INJURED] = new fireState();
}     }
void repair()
{
auto injuredVal = mStates.find(INJURED);
if(injuredVal == mStates.end())
return;
auto result = mStates.find(REPAIR);
if(result == mStates.end())
{
mStates[REPAIR] = new repairState();
}     }
};

#endif


客户端代码main.cpp:

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

using namespace std;
class SiegeTank;

void main()
{
concreteBuilding cb("兵营");
cb.production();
cb.injured();
cb.repair();
cb.show();
return;
}


结果:



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