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();
相关推荐
杜子不疼.6 小时前
【C++ AI 大模型接入 SDK】 - DeepSeek 模型接入(上)
开发语言·c++·chatgpt
前端不太难6 小时前
从单页面到系统化:鸿蒙 App 演进路径
华为·状态模式·harmonyos
石山代码7 小时前
C++ 内存分区 堆区
java·开发语言·c++
张小姐的猫9 小时前
【Linux】多线程 —— 线程互斥
linux·运维·服务器·c++
做人求其滴11 小时前
面试经典 150 题 380 274
c++·算法·面试·职场和发展·力扣
见叶之秋11 小时前
C++基础入门指南
开发语言·c++
计算机安禾12 小时前
【c++面向对象编程】第42篇:模板特化与偏特化:为特定类型定制实现
开发语言·c++·算法
玖釉-12 小时前
C++ 中的循环语句详解:while、do...while、for、嵌套循环与循环控制
开发语言·c++·算法
欧米欧13 小时前
C++进阶数据结构之搜索二叉树
开发语言·数据结构·c++
青小莫13 小时前
C++之vector讲解
c++·stl