C++ 设计模式之状态模式

C++ 设计模式之状态模式

简介

1、状态模式 (State)是一种行为型设计模式,它允许一个对象在其内部状态发生改变时改变它的行为,对象看起来似乎修改了它的类。该模式主要用于实现一个对象在多种状态转换时能够自动切换到正确的行为。

2、状态模式 (State)应用场景包括但不限于:

2.1、当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时。

2.2、一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

3、状态模式 (State)的构成

3.1、状态基类

c 复制代码
class State
{
public:
	virtual ~State() {}
	virtual void handleInput(CharacterContext& context, char input) = 0;
	virtual void update(CharacterContext& context) = 0;
};

3.2、具体状态类

c 复制代码
class StandingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

4、状态模式 (State)的优点

4.1、封装性:状态的变更逻辑和动作执行封装在状态对象中,易于维护和扩展。

4.2、去除庞大的条件分支语句:状态模式通过把各种状态转移逻辑分布到状态对象中,去掉了原系统中对象的行为巨大且复杂的条件分支语句。

4.3、集中化状态管理:所有状态相关的代码都存在于某个State子类中,易于理解。

4.4、维护和扩展更简单:新增状态只需增加新的状态类,不需改变已有的状态类和上下文。

5、状态模式 (State)的缺点

5.1、类膨胀:如果状态很多,而且状态的逻辑也很复杂,就可能会产生很多的状态类,导致系统变得非常庞大。

5.2、依赖性:状态模式把各种状态对象的逻辑都分布在各个状态类中,每个状态类都依赖上下文对象,这增加了各个类之间的依赖性。

简单示例

1、定义

c 复制代码
class State
{
public:
	virtual ~State() {}
	virtual void handleInput(CharacterContext& context, char input) = 0;
	virtual void update(CharacterContext& context) = 0;
};

class StandingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class JumpingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class DuckingState : public State
{
public:
	void handleInput(CharacterContext& context, char input);
	void update(CharacterContext& context);
};

class CharacterContext
{
public:
	CharacterContext(State* initialState);
	~CharacterContext();
	void handleInput(char input);
	void changeState(State* newState);
	void update();
private:
	State* currentState;
};

2、实现

c 复制代码
void StandingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'D')
	{
		context.changeState(new DuckingState());
	}
	else if (input == 'J')
	{
		context.changeState(new JumpingState());
	}
}

void StandingState::update(CharacterContext& context)
{
	std::cout << "Character is standing." << std::endl;
}

void JumpingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'D')
	{
		context.changeState(new DuckingState());
	}
}

void JumpingState::update(CharacterContext& context)
{
	std::cout << "Character is jumping." << std::endl;
}

void DuckingState::handleInput(CharacterContext& context, char input)
{
	if (input == 'S')
	{
		context.changeState(new StandingState());
	}
}

void DuckingState::update(CharacterContext& context)
{
	std::cout << "Character is ducking." << std::endl;
}

CharacterContext::CharacterContext(State* initialState) : currentState(initialState)
{

}

CharacterContext::~CharacterContext()
{
	delete currentState;
}

void CharacterContext::handleInput(char input)
{
	currentState->handleInput(*this, input);
}

void CharacterContext::changeState(State* newState)
{
	delete currentState;
	currentState = newState;
}

void CharacterContext::update()
{
	currentState->update(*this);
}

3、调用

c 复制代码
CharacterContext character(new StandingState());
character.handleInput('D');
character.update();
相关推荐
凌云行者29 分钟前
OpenGL入门005——使用Shader类管理着色器
c++·cmake·opengl
凌云行者32 分钟前
OpenGL入门006——着色器在纹理混合中的应用
c++·cmake·opengl
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
可均可可2 小时前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
白子寰2 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
小芒果_012 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
gkdpjj2 小时前
C++优选算法十 哈希表
c++·算法·散列表
王俊山IT2 小时前
C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(5)
开发语言·c++·笔记·学习
-Even-2 小时前
【第六章】分支语句和逻辑运算符
c++·c++ primer plus
我是谁??3 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++