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();
相关推荐
YuforiaCode5 分钟前
第十二届蓝桥杯 2021 C/C++组 卡片
c语言·c++·蓝桥杯
学习机器不会机器学习2 小时前
深入浅出JavaScript常见设计模式:从原理到实战(2)
开发语言·javascript·设计模式
努力努力再努力wz2 小时前
【Linux实践系列】:进程间通信:万字详解命名管道实现通信
android·linux·运维·服务器·c++·c
碎梦归途2 小时前
23种设计模式-行为型模式之命令模式(Java版本)
java·开发语言·jvm·设计模式·命令模式·行为型模式
炯哈哈3 小时前
【上位机——MFC】文档
开发语言·c++·mfc·上位机
愚润求学3 小时前
【C++11】可变参数模板
开发语言·c++·笔记·c++11·模板
WW_千谷山4_sch3 小时前
MYOJ_1349:(洛谷P3951)[NOIP 2017 提高组] 小凯的疑惑(数学公式套用,两步搞定代码)
c++·算法
共享家95274 小时前
深入探究C++ 中的stack、queue和deque
c++
How_doyou_do4 小时前
项目实战-贪吃蛇大作战【补档】
c语言·c++·visual studio
Ethon_王4 小时前
走进Qt--信号与槽机制详解与实战
c++·qt