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();
相关推荐
渝妳学C26 分钟前
【C++】类和对象(下)
c++
EleganceJiaBao40 分钟前
【C语言】结构体模块化编程
c语言·c++·模块化·static·结构体·struct·耦合
xianwu5431 小时前
反向代理模块。开发
linux·开发语言·网络·c++·git
Bucai_不才1 小时前
【C++】初识C++之C语言加入光荣的进化(上)
c语言·c++·面向对象
木向1 小时前
leetcode22:括号问题
开发语言·c++·leetcode
筑基.1 小时前
basic_ios及其衍生库(附 GCC libstdc++源代码)
开发语言·c++
yuyanjingtao2 小时前
CCF-GESP 等级考试 2023年12月认证C++三级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
越甲八千3 小时前
重温设计模式--代理、中介者、适配器模式的异同
设计模式·适配器模式
王老师青少年编程3 小时前
gesp(二级)(12)洛谷:B3955:[GESP202403 二级] 小杨的日字矩阵
c++·算法·矩阵·gesp·csp·信奥赛
OTWOL4 小时前
两道数组有关的OJ练习题
c语言·开发语言·数据结构·c++·算法