入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

使用C++实现一套简单的状态机模型——实例

创建时间:2015-03-07 投稿人: 浏览次数:193

        一般来说,“状态机”是一种表达状态转换变换逻辑的方法。曾经有人和我讨论过为什么不直接用ifelse,而要使用“状态机”去实现一些逻辑,认为使用“状态机”是一种炫技的表现。然而对于大型复杂逻辑的变化和跳转,使用ifelse将带来代码难以阅读等弊端。其实ifelse也是一种状态机实现的方式。

        之前我们有个业务和操作系统有着强烈的关联,而我们希望比较清晰地描述整个业务中各个子业务的过程,就引入了状态机描述的方式。可是当时的状态机是使用if else方法描述,显得整个过程比较臃肿,阅读起来也不够清晰。于是我尝试引入第三方的状态机库来重构这块的业务——比如boost里的状态机库。可是使用过程中感觉到了很多不便,索性自己动手实现一套清晰优雅的状态机模型。(转载请指明出于breaksoftware的csdn博客)

       编写模型之前,我们需要了解什么是状态机。我在搜索引擎上搜索到了若干结果,但是大部分都显得非常学术化。而实现一个大而全、包罗万象、放之四海而皆适宜的状态机模型也并非我的设计初衷。我设计的状态机具有如下特性:单线程、浅历史。单线程即我们的状态机是在一个线程内部运行的,不受外界其他线程干扰,这样我们在设计时就不用考虑多线程编程的问题。浅历史是状态机中的一个概念,它是指只记录最高一层复合状态的最后离开状态。这个特性如果有不了解的,可以先去搜索下。在实践中,该特性还是非常有用的。

        我们以一个简单、可能不恰当的例子来引入我这个状态机。我们先设计一个应用场景:给用户电脑安装软件并运行。这个场景我们可以拆分为如下几个逻辑:

  1. 检测是否安装
  2. 下载安装包
  3. 解压安装包并安装
  4. 运行

        这四个逻辑并不复杂,我们将其定义为基础状态——一种可以持续一段时间且内部执行逻辑我们不关心的状态。为了让这个逻辑变得稍微有点复杂,我们设计如下要求:

        对于未安装该软件的情况:

  • 从A地址下载安装包失败后从B地址下载
  • 从B地址下载安装包失败后从C地址下载
  • 从C地址下载安装包失败后认为执行失败
  • 下载成功后,检测CPU是否繁忙
  • CPU繁忙则继续检测CPU是否繁忙
  • CPU不繁忙则执行解压
  • 解压失败则重新下载。如果之前后A地址下载,则本次从B地址下载;如果之前从B地址下载,则本次从C地址下载
  • 解压成功后执行
  • 运行失败则重新下载。如果之前后A地址下载,则本次从B地址下载;如果之前从B地址下载,则本次从C地址下载
  • 运行成功则认为执行成功
        对于已安装该软件的情况:
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。