状态模式(State Pattern)

状态模式(State Pattern)
如果任务的执行过程是有多个不同状态的(比如初始化、运行中、完成等),你可以使用状态模式。每个状态可以有不同的行为,使得任务的状态管理更加清晰和可维护。

示例:
class TaskState {
public:virtual void handle() = 0;  // 处理状态
};class InitializedState : public TaskState {
public:void handle() override {// 初始化状态下的处理}
};class RunningState : public TaskState {
public:void handle() override {// 运行状态下的处理}
};class Task {
private:TaskState *state;public:void setState(TaskState *state) {this->state = state;}void run() {state->handle();}
};






状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,从而让对象看起来像是改变了其类。这种模式非常适合处理对象在不同状态下具有不同行为的场景。

状态模式的核心概念

  1. Context(上下文)

    • 包含一个对状态对象的引用,通过这个引用调用状态对象的方法。
    • 客户端通过上下文对象与状态对象交互。
  2. State(状态接口)

    • 定义了一个接口,用于封装与状态相关的操作。
    • 所有具体状态类都实现这个接口。
  3. ConcreteState(具体状态类)

    • 实现了状态接口,具体定义了对象在某个状态下的行为。
    • 可以访问上下文对象,以便在需要时改变上下文的状态。

示例代码解析

以下是一个完整的状态模式示例,包括上下文类、状态接口和具体状态类。

1. 状态接口(State)
class TaskState {
public:virtual ~TaskState() {}virtual void handle(Task* task) = 0;  // 处理状态
};
2. 具体状态类(ConcreteState)
class InitializedState : public TaskState {
public:void handle(Task* task) override {std::cout << "Task is in Initialized State" << std::endl;// 初始化状态下的处理逻辑// 可以在这里改变任务的状态task->setState(new RunningState());}
};class RunningState : public TaskState {
public:void handle(Task* task) override {std::cout << "Task is in Running State" << std::endl;// 运行状态下的处理逻辑// 可以在这里改变任务的状态task->setState(new CompletedState());}
};class CompletedState : public TaskState {
public:void handle(Task* task) override {std::cout << "Task is in Completed State" << std::endl;// 完成状态下的处理逻辑// 任务完成,不再改变状态}
};
3. 上下文类(Context)
class Task {
private:TaskState* state;public:Task() : state(nullptr) {}void setState(TaskState* newState) {if (state) {delete state;  // 释放旧状态}state = newState;}void run() {if (state) {state->handle(this);  // 调用当前状态的处理方法}}~Task() {if (state) {delete state;  // 释放状态对象}}
};

使用示例

以下是如何使用状态模式来管理任务状态的示例:

#include <iostream>int main() {// 创建任务对象Task task;// 设置初始状态为初始化状态task.setState(new InitializedState());// 运行任务task.run();  // 输出: Task is in Initialized Statetask.run();  // 输出: Task is in Running Statetask.run();  // 输出: Task is in Completed Statereturn 0;
}

输出

Task is in Initialized State
Task is in Running State
Task is in Completed State

状态模式的用途

  1. 清晰的状态管理

    • 状态模式将每个状态的行为封装在独立的类中,使得状态管理更加清晰和可维护。
    • 每个状态类只关注自己的行为,符合单一职责原则。
  2. 动态状态切换

    • 对象可以在运行时动态切换状态,而不需要在上下文类中编写大量的条件语句。
    • 状态的切换逻辑由状态类本身管理,减少了上下文类的复杂性。
  3. 扩展性

    • 添加新的状态时,只需添加一个新的状态类,而不需要修改现有的上下文类或状态类。
    • 符合开闭原则(对扩展开放,对修改封闭)。

与状态观测器的关系

状态模式和状态观测器(Observer Pattern)是两种不同的设计模式,但它们可以结合使用:

  • 状态模式

    • 主要用于管理对象的内部状态和行为。
    • 通过状态类的切换来改变对象的行为。
  • 状态观测器(Observer Pattern)

    • 主要用于实现对象之间的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。
    • 适用于多对多的依赖关系,例如事件驱动系统。

结合使用示例

假设你需要在任务状态改变时通知其他对象,可以结合状态模式和状态观测器模式:

  1. 定义 Observer 接口

    class Observer {
    public:virtual void update(const std::string& message) = 0;
    };
    
  2. 定义 Subject 类

    class Subject {
    private:std::vector<Observer*> observers;
    public:void attach(Observer* observer) {observers.push_back(observer);}void notify(const std::string& message) {for (Observer* observer : observers) {observer->update(message);}}
    };
    
  3. 让 Task 类继承 Subject

    class Task : public Subject {
    private:TaskState* state;public:Task() : state(nullptr) {}void setState(TaskState* newState) {if (state) {delete state;}state = newState;notify("Task state changed");  // 通知观察者}void run() {if (state) {state->handle(this);}}~Task() {if (state) {delete state;}}
    };
    
  4. 定义具体的 Observer

    class TaskLogger : public Observer {
    public:void update(const std::string& message) override {std::cout << "Log: " << message << std::endl;}
    };
    
  5. 使用示例

    int main() {Task task;task.attach(new TaskLogger());task.setState(new InitializedState());task.run();task.run();task.run();return 0;
    }
    

输出

Log: Task state changed
Task is in Initialized State
Log: Task state changed
Task is in Running State
Log: Task state changed
Task is in Completed State

总结

  • 状态模式:用于管理对象的内部状态和行为,通过状态类的切换来改变对象的行为。
  • 状态观测器模式:用于实现对象之间的依赖关系,当一个对象的状态改变时,通知所有依赖于它的对象。
  • 结合使用:可以通过状态模式管理状态,同时使用状态观测器模式通知其他对象状态的变化。

希望这些解释和示例能帮助你更好地理解状态模式及其用途。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/41549.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Flutter实战:19-Flutter集成高德地图,跳转页面方式

前言 在之前的文章现有Flutter项目支持鸿蒙II中&#xff0c;介绍了如何使用第三方插件&#xff0c;同时给出了非常多的使用案例&#xff0c;如 flutter_inappwebview&#xff0c;video_player, image_picker 等&#xff0c;本文将开始介绍如何集成高德地图。 整体方案 通过 …

26考研——图_图的代码实操(6)

408答疑 文章目录 五、图的代码实操图的存储邻接矩阵结构定义初始化插入顶点获取顶点位置在顶点 v1 和 v2 之间插入边获取第一个邻接顶点获取下一个邻接顶点显示图 邻接表结构定义初始化图插入顶点获取顶点位置在顶点 v1 和 v2 之间插入边获取第一个邻接顶点获取下一个邻接顶点…

力扣32.最长有效括号(栈)

32. 最长有效括号 - 力扣&#xff08;LeetCode&#xff09; 代码区&#xff1a; #include<stack> #include<string> /*最长有效*/ class Solution { public:int longestValidParentheses(string s) {stack<int> st;int ans0;int ns.length();st.push(-1);fo…

Node.js 下载安装及环境配置教程、卸载删除环境配置超详细步骤(附图文讲解!) 从零基础入门到精通,看完这一篇就够了

Node.js 安装 一、进入官网地址下载安装包 Node.js — Download Node.js 选择对应你系统的Node.js版本&#xff0c;这里我选择的是Windows系统、64位 Tips&#xff1a;如果想下载指定版本&#xff0c;点击【以往的版本】&#xff0c;即可选择自己想要的版本下载 二、安装程序…

SQLark导出功能详解|轻松管理数据库数据与结构

SQLark 作为一款数据库管理工具&#xff0c;为用户提供了丰富且实用的导出功能。在数据库管理与开发过程中&#xff0c;数据及结构的导出操作至关重要&#xff0c;关乎数据的迁移、备份、版本管理以及问题定位等诸多关键环节。接下来&#xff0c;让我们深入了解 SQLark 的导出功…

搭建Redis主从集群

主从集群说明 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。 主从结构 这是一个简单的Redis主从集群结构 集群中有一个master节点、两个slave节点&#xff08;现在叫replica&#xff09;…

自然语言处理(NLP)技术的应用面有哪些

自然语言处理&#xff08;NLP&#xff09;技术在各个领域都有广泛的应用&#xff0c;以下是一些常见的例子&#xff1a; 机器翻译&#xff1a;NLP技术用于开发翻译系统&#xff0c;可以将一个语言的文本自动翻译成另一种语言。例如&#xff0c;谷歌翻译就是一个应用了NLP技术的…

element-plus 的简单应用

前言 本篇博客是 基于 ElementPlus 快速入门_element plus x-CSDN博客 的进阶 最终成果 完成的要求 1 深入学习 设计 | Element Plus 从里面找自己合适的 使用到的 组件有&#xff1a;表格&#xff0c;分页条&#xff0c;表单&#xff0c;卡片 2 具备 前端基础&#xff08;ht…

关于Qt的各类问题

目录 1、问题&#xff1a;Qt中文乱码 2、问题&#xff1a;启动时避免ComBox控件出现默认值 博客会不定期的更新各种Qt开发的Bug与解决方法,敬请关注! 1、问题&#xff1a;Qt中文乱码 问题描述&#xff1a;我在设置标题时出现了中文乱码 this->setWindowTitle("算法…

海思烧录工具HITool电视盒子刷机详解

HiTool是华为开发的一款用于海思芯片设备的刷机和调试工具&#xff0c;可对搭载海思芯片的机顶盒、智能电视等设备进行固件烧录、参数配置等操作。以下为你详细介绍&#xff1a; 功能用途 固件烧录&#xff1a;这是HiTool最主要的功能之一。它能够将下载好的适配固件文件烧录到…

Docker Compose介绍

基本概念 Docker-Compose是Docker官方的开源项目&#xff0c;负责实现对docker容器集群的快速编排。 可以这么理解&#xff0c;docker compose是docker提出的一个工具软件&#xff0c;可以管理多个docker容器组成一个应用&#xff0c;只需要编写一个YAML格式的配置文件docker…

大疆上云api直播功能如何实现

概述 流媒体服务器作为直播画面的中转站,它接收推流端的相机画面,同时拉流端找它获取相机的画面。整个流程如下: 在流媒体服务器上创建流媒体应用(app),一个流媒体服务器上面可以创建多个流媒体应用约定推拉流的地址。假设流媒体服务器工作在1935端口上面,假设创建的流…

LabVIEW远程控制通讯接口

abVIEW提供了多种远程控制与通讯接口&#xff0c;适用于不同场景下的设备交互、数据传输和系统集成。这些接口涵盖从基础的网络协议&#xff08;如TCP/IP、UDP&#xff09;到专用技术&#xff08;如DataSocket、远程面板&#xff09;&#xff0c;以及工业标准协议&#xff08;如…

算法每日一练 (18)

&#x1f4a2;欢迎来到张翊尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 算法每日一练 (18)删除并获得点数题目描述解题思路解题…

Java后端API限流秘籍:高并发的防护伞与实战指南

目录导航 📜 🛡️ 为什么需要API限流?🧠 主流限流算法大解析👩‍💻 阿里巴巴的限流实践📏 四大黄金定律🤼 限流策略组合拳🏆 限流场景实战💻 技术实现方案🌟 最佳实践分享📈 结语与展望📚 推荐阅读 1. 🛡️ 为什么需要API限流? 在高并发环境中,未…

【软件测试】:软件测试实战

1. ⾃动化实施步骤 1.1 编写web测试⽤例 1.2 ⾃动化测试脚本开发 common public class AutotestUtils {public static EdgeDriver driver;// 创建驱动对象public static EdgeDriver createDriver(){// 驱动对象已经创建好了 / 没有创建if( driver null){driver new EdgeDr…

26考研——栈、队列和数组_栈(3)

408答疑 文章目录 一、栈1、栈&#xff08;Stack&#xff09;的概念和特点定义术语操作特性示例直观理解栈的基本操作初始化栈判断栈是否为空入栈操作出栈操作读取栈顶元素销毁栈 栈的数学性质 2、栈的顺序存储结构顺序栈的定义栈顶指针初始化注意事项 共享栈共享栈的操作共享栈…

基于Spring Boot的ONLY在线商城系统设计与实现的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

信息安全的数学本质与工程实践

信息安全的本质是数学理论与工程实践的高度统一。在这个数字空间与物理世界深度融合的时代&#xff0c;信息安全已从简单的数据保护演变为维系数字社会正常运转的基础设施。对于计算机专业学习者而言&#xff0c;理解信息安全需要超越工具化认知&#xff0c;深入其数学内核与系…

网站迁移监测体系:301重定向与流量波动预警机制

网站迁移监测体系&#xff1a;301重定向与流量波动预警机制 引言 在网站迁移过程中&#xff0c;确保用户体验的连续性和搜索引擎优化&#xff08;SEO&#xff09;的稳定性是至关重要的。301重定向作为一种永久性重定向技术&#xff0c;能够有效地将旧页面的权重和流量传递到新…