状态模式的C++实现示例

news/2025/3/14 13:29:55/

核心思想

状态模式(State Pattern) 是一种行为设计模式,允许对象在其内部状态改变时改变其行为。它将状态相关的逻辑分散到不同的状态类中,避免了使用大量的条件语句来处理不同状态下的行为。

状态抽象化:将对象的状态抽象为独立的类,每个状态类实现与该状态相关的行为。
上下文委托:上下文对象(Context)持有一个状态对象的引用,并将行为委托给当前状态对象。
状态切换:状态类负责在适当的时候切换到其他状态,上下文对象只需更新当前状态的引用。

使用场景

对象的行为依赖于它的状态,并且需要在运行时根据状态改变行为。
代码中包含大量与状态相关的条件分支,且这些分支在多个地方重复出现。
需要清晰地管理状态的转换逻辑,避免状态相关的代码分散在多个地方。

优点

消除条件分支:将状态相关的逻辑分散到状态类中,避免了复杂的条件判断。
易于扩展:新增状态时只需添加新的状态类,无需修改现有代码。
提高可读性:状态转换逻辑集中在状态类中,代码更清晰易懂。

缺点

类数量增加:每个状态都需要一个类,可能会导致类的数量膨胀。
状态转换逻辑分散:状态转换逻辑分布在各个状态类中,可能会增加调试难度。

示例代码

#include <iostream>
#include <memory>// 前向声明
class State;// 上下文类:电灯
class Light {
private:std::shared_ptr<State> state_; // 当前状态public:Light(std::shared_ptr<State> state);void setState(std::shared_ptr<State> state); // 设置状态void pressSwitch(); // 按下开关
};// 抽象状态类
class State {
public:virtual ~State() = default;virtual void handle(Light& light) = 0; // 处理行为
};// 具体状态类:开状态
class OnState : public State {
public:void handle(Light& light) override;
};// 具体状态类:关状态
class OffState : public State {
public:void handle(Light& light) override;
};// Light 类的实现
Light::Light(std::shared_ptr<State> state) : state_(state) {}void Light::setState(std::shared_ptr<State> state) {state_ = state;
}void Light::pressSwitch() {state_->handle(*this); // 委托给当前状态处理
}// OnState 类的实现
void OnState::handle(Light& light) {std::cout << "Turning light off." << std::endl;light.setState(std::make_shared<OffState>()); // 切换到关状态
}// OffState 类的实现
void OffState::handle(Light& light) {std::cout << "Turning light on." << std::endl;light.setState(std::make_shared<OnState>()); // 切换到开状态
}// 客户端代码
int main() {// 初始状态为关Light light(std::make_shared<OffState>());// 按下开关,切换状态light.pressSwitch(); // 开light.pressSwitch(); // 关light.pressSwitch(); // 开return 0;
}

输出结果

Turning light on.
Turning light off.
Turning light on.

代码解析

Light 类:上下文类,持有一个状态对象的指针,并将行为委托给当前状态。
State 类:抽象状态类,定义了状态的行为接口。
OnState 和 OffState 类:具体状态类,实现了状态的行为和状态转换逻辑。
状态切换:在 handle 方法中,状态类负责切换到下一个状态。


http://www.ppmy.cn/news/1578792.html

相关文章

单元测试、系统测试和集成测试知识总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、单元测试的概念 单元测试是对软件基本组成单元进行的测试&#xff0c;如函数或一个类的方法。当然这里的基本单元不仅仅指的是一个函数或者方法&#xff…

3.3.2 Proteus第一个仿真图

文章目录 文章介绍0 效果图1 新建“点灯”项目2 添加元器件3 元器件布局接线4 补充 文章介绍 本文介绍&#xff1a;使用Proteus仿真软件画第一个仿真图 0 效果图 1 新建“点灯”项目 修改项目名称和路径&#xff0c;之后一直点“下一步”直到完成 2 添加元器件 点击元…

深入解析Go语言Channel:源码剖析与并发读写机制

文章目录 Channel的内部结构Channel的创建过程有缓冲Channel的并发读写机制同时读写的可能性发送操作的实现接收操作的实现 并发读写的核心机制解析互斥锁保护环形缓冲区等待队列直接传递优化Goroutine调度 实例分析&#xff1a;有缓冲Channel的并发读写性能优化与最佳实践缓冲…

简记_开关电源基础知识(一)

1.1、开关电源的类型 线性稳压器&#xff08;LDO&#xff09; 开关稳压器 电荷泵 传输元件 BJT&#xff08;双极型晶体管&#xff09; FET&#xff08;场效应晶体管&#xff09; BJT或FET 储能元件 电容 电感和电容 电容 工作模式 工作在线性区 无开关跳变 开关&a…

WireShark自动抓包

背景 异常流量检测是当前保护网络空间安全的重要检测方法。 对流量的研究&#xff0c;首先需要在系统中进行抓包&#xff0c;并对包进行分析。 这里对WireShark自动抓包进行简要介绍。 操作步骤 1、选择“捕获”>“选项”。 2、在Input下&#xff0c;选择要抓包的网络接…

使用AI一步一步实现若依前端(11)

功能11&#xff1a;实现面包屑功能 功能10&#xff1a;添加首页菜单项 功能9&#xff1a;退出登录功能 功能8&#xff1a;页面权限控制 功能7&#xff1a;路由全局前置守卫 功能6&#xff1a;动态添加路由记录 功能5&#xff1a;侧边栏菜单动态显示 功能4&#xff1a;首页使用…

bug修改模板(日志)

第一段&#xff1a;前端报错&#xff1a;Uncaught (in promise) TypeError: Cannot read properties of undefined (reading bookDetailList) 第二段&#xff1a;后端报错&#xff1a;Failed to convert value of type ‘java.lang.String‘ to required type ‘java.lang.Lon…

idea超级AI插件,让 AI 为 Java 工程师

引言​ 用户可在界面中直接通过输入自然语言的形式描述接口的需求&#xff0c;系统通过输入的需求自动分析关键的功能点有哪些&#xff0c;并对不确定方案的需求提供多种选择&#xff0c;以及对需求上下文进行补充&#xff0c;用户修改确定需求后&#xff0c;系统会根据需求设…