文章目录

  • 概念
  • UML结构图
  • 代码实现
  • 状态模式的使用场景

概念

状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为。
在探讨状态模式的优雅之前,先来看看以下代码场景;

enum StateType
{Red,Green,Yellow
};void handle(int stateType)
{while(1){switch (stateType) {case Green:{qDebug()<<QStringLiteral("绿灯通行90秒");QThread::sleep(90);stateType = Yellow;}break;case Red:{qDebug()<<QStringLiteral("红灯禁行60秒");QThread::sleep(60);stateType = Green;}break;case Yellow:{qDebug()<<QStringLiteral("黄灯等3秒");QThread::sleep(3);stateType = Red;}break;default:break;}}}

输出:
“绿灯通行90秒”
“黄灯等3秒”
“红灯禁行60秒”

“绿灯通行90秒”
“黄灯等3秒”
“红灯禁行60秒”
handle()函数是一个基于 switch语句的状态机。模拟红绿灯,在每一个状态下,都会有不同的行为。假如需要增加新的状态类型时,我们又需要修改原来的代码,这违背了开闭原则。状态模式就是用来解决这种随着状态增加而出现多分支结构的问题,就像工厂模式消除了简单工厂模式的分支语句一样。

UML结构图


状态模式将基于switch语句的状态机转换为对象,将各种状态转换逻辑分布到State的子类之间。
这个结构可能看上去与策略模式相似, 但有一个关键性的不同——在状态模式中, 特定状态知道其他所有状态的存在, 且能触发从一个状态到另一个状态的转换; 策略则几乎完全不知道其他策略的存在。,策略模式是让用户指定更换策略的算法,而状态模式是状态在满足一定条件下的自动更换,用户无法指定状态,最多只能设置初始状态。

代码实现

将以上代码以状态模式的思想重构,将会变成以下写法
.h文件

#ifndef STATEPATTERN_H
#define STATEPATTERN_H
#include<iostream>
#include<QThread>
#include<QDebug>
using namespace std;class Context;class State
{public:State(){}virtual void handle(Context* context) = 0;
};class Red : public State
{public:Red(){}void handle(Context* context) override;
};class Green : public State
{public:Green(){}void handle(Context* context) override;};class Yellow : public State
{public:Yellow(){}void handle(Context* context) override;
};class Context
{public:Context(State *state) {m_state = state;}void changeState(State *state){if(m_state)delete m_state;m_state = state;}void action();private:State *m_state;
};
#endif // STATEPATTERN_H

.cpp文件

void Red::handle(Context *context){qDebug()<<QStringLiteral("红灯禁行60秒");QThread::sleep(60);context->changeState(new Green());
}void Green::handle(Context *context){qDebug()<<QStringLiteral("绿灯通行90秒");QThread::sleep(90);context->changeState(new Yellow());
}void Yellow::handle(Context *context){qDebug()<<QStringLiteral("黄灯等3秒");QThread::sleep(3);context->changeState(new Red());
}void Context::action(){if(m_state){m_state->handle(this);}
}

客户端

    State* ptState = new Green();Context* ptContext = new Context(ptState);while(1){ptContext->action();}delete ptState;delete ptContext;

输出:
“绿灯通行90秒”
“黄灯等3秒”
“红灯禁行60秒”

“绿灯通行90秒”
“黄灯等3秒”
“红灯禁行60秒”

状态模式的使用场景

如果状态机只有很少的状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作。
1.如果对象需要根据自身当前状态进行不同行为, 同时状态的数量非常多且与状态相关的代码会频繁变更的话, 可使用状态模式。
2.如果某个类需要根据成员变量的当前值改变自身行为, 从而需要使用大量的条件语句时, 可使用该模式。
参考文献:https://refactoringguru.cn/design-patterns/state

GoF设计模式——状态模式(C++实现)相关推荐

  1. C++设计模式——状态模式

    C++设计模式--状态模式 在实际开发中,我们经常会遇到这种情况:一个对象有多种状态,在每一个状态下,都会有不同的行为.那么在代码中我们经常是这样实现的.   1 2 3 4 5 6 7 8 9 10 ...

  2. Python设计模式-状态模式

    Python设计模式-状态模式 代码基于3.5.2,代码如下; #coding:utf-8 #状态模式class state():def writeProgram(self,work):raise N ...

  3. Java 设计模式——状态模式

    概述 很多人在说状态模式的时候总拿策略模式来进行对比,可能他们的类图会有一点类似,可我却不认为他们有多么相像.你可以阅读<Java设计模式--策略模式>这篇博客,并与本文对比,以找到蛛丝马 ...

  4. 设计模式状态模式uml_UML的完整形式是什么?

    设计模式状态模式uml UML:统一建模语言 (UML: Unified Modeling Language) UML is an abbreviation of Unified Modeling L ...

  5. Java 有限状态机 (设计模式——状态模式)

    Java 有限状态机 (设计模式--状态模式) 编写代码的时候,有时会遇见较为复杂的swith...case...和if...else...语句.这一刻有时会想到状态机,用有限状态机替换swith.. ...

  6. C++设计模式——状态模式(state pattern)

    一.原理讲解 别名状态对象(object for state). 1.1意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 1.2应用场景 一个对象的行为取决于它的状态,并 ...

  7. 设计模式——状态模式详解

    0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...

  8. 大话设计模式—状态模式

    在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象. 大话设 ...

  9. C++设计模式-状态模式

    目录 基本概念 代码与实例 基本概念 状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来就像是改变了其类: 状态模式的好处: 1. 将与特定状态相关的行为局部化,并且将不 ...

最新文章

  1. python数据转换函数_常用python数据类型转换函数总结
  2. R最快且比dplyr最高效的大数据处理R包:tidyfst
  3. hdu 1163 ( 求n^n位根)
  4. 企业大数据运用实战案例分享
  5. 【Android 高性能音频】OboeTester 音频性能测试应用 ( Oboe 输出测试参数 | API 选择 | 音频输出设备选择 | 采样率 | 通道 | 采样格式 | 播放偏好 )
  6. thinkphp项目mysql类关系_ThinkPHP数据库与模型
  7. 公众号 -「前端攻略 开光篇」
  8. 5.1 vim介绍 5.2-5.3 vim颜色显示和移动光标、vim一般模式下移动光标 5.4 vim 一般模式下复制剪切粘贴...
  9. Springboot vue.js html 跨域 前后分离 Activiti6 shiro 权限
  10. Fire Net C++
  11. C++ Primer 第5版--练习9.31
  12. 按英语体育计算机创建透视表,2016年职称计算机考试模拟练习题
  13. MySQL基础入门-创建表格系列操作
  14. 影响手机成像质量的因素
  15. Unity Shader - Specular mode: Specular parameter 高光模式中的高光参数
  16. .net是什么域名?域名注册需要实名制吗?
  17. JavaWeb题库整理
  18. Discarding record on action DISCARD on error 0
  19. 无法支持计算机上的硬件,电脑经常弹出“不支持的硬件”怎么办?
  20. 第五章:MySQL主从复制

热门文章

  1. 提高iTunes更新速度的DNS
  2. STFT的综合分析--滤波器组求和(FBS)和叠相相加(OLA)
  3. 平均值、标准差、相关系数、回归线及最小二乘法
  4. 快速提高计算能力——matlab多项式计算
  5. 自制肥鲨HDO2电源降压延长线,支持3S~6S动力电池
  6. PHP安装容易遇到的问题,安装php可能会遇到的问题
  7. Microsoft Word 教程「7」,如何在 Word 中显示标尺?
  8. Django和layim实现websocket
  9. 如何获取维普免费账号--在校外下载维普万方等全文
  10. 献给经常加班熬夜的你们