运行在VS2022,x86,Debug下。
28. 状态模式
- 状态模式让一个对象的行为随着内部状态的改变而改变,而该对象也像换了类一样。
- 应用:如在游戏开发中,游戏有不同场景,如主菜单、开始、战斗等。可以使用状态模式,定义一个场景状态接口, 然后分别实现主菜单状态类、开始状态类、战斗状态类,实现游戏场景的切换。
- 实现
- 抽象状态类,即定义状态接口。
- 具体状态类,即实现状态接口。
- 上下文类,状态控制者。
- 代码如下。
//抽象状态类:场景状态接口
class SceneState
{
public:
virtual void load() = 0;
virtual void update() = 0;
virtual void render() = 0;
virtual void unload() = 0;
};
//具体状态类:主菜单状态类
class MainMenuState :public SceneState
{
public:
void load() { cout << "Loading main menu..." << endl; }
void update() { cout << "Updating main menu..." << endl; }
void render() { cout << "Rendering main menu..." << endl; }
void unload() { cout << "Unloading main menu..." << endl; }
};
//具体状态类:战斗状态类
class BattleState :public SceneState
{
public:
void load() { cout << "Loading battle scene..." << endl; }
void update() { cout << "Updating battle scene..." << endl; }
void render() { cout << "Rendering battle scene..." << endl; }
void unload() { cout << "Unloading battle scene..." << endl; }
};
//上下文类,状态控制者
class Context
{
private:
SceneState* currentState; //保存当前状态
public:
Context(SceneState* initialState):currentState(initialState){}
void setState(SceneState* state) //切换状态
{
if (currentState) currentState->unload(); //切换状态前先卸载当前状态
currentState = state;
state->load(); //加载新状态
}
void update() { currentState->update(); }
void render() {currentState->render(); }
};
int main()
{
MainMenuState mainMenu;
BattleState batteScene;
//从主菜单场景切换到战斗场景
Context context(&mainMenu);
context.render();
context.setState(&batteScene);
context.update();
context.render();
return 0;
}
注意 虽然策略模式和状态模式看起来很像,但是关注点不同。
- 状态模式强调对象状态和行为之间的关联。
- 策略模式强调算法之间的独立性和可互换性。