【转】深入浅出理解有限状态机

转自:深入浅出理解有限状态机 - 知乎

有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。比如下图非常有名的TCP协议状态机。
 


其实我们在编程时实现相关业务逻辑时经常需要处理各种事件和状态切换,写各种switch/case 和if/else ,所以我们其实可能一直都在跟有限状态机打交道,只是可能没有意识到。在处理一些业务逻辑比较复杂的需求时,可以先看看是否适合用一个有限状态机来描述,如果可以把业务模型抽象成一个有限状态机,那么代码就会逻辑特别清晰,结构特别规整。
下面我们就来聊聊所谓的状态机,以及它如何在代码中实现。
1、状态机的要素
状态机可归纳为4个要素,即现态、条件、动作、次态。“现态”和“条件”是因,“动作”和“次态”是果。详解如下:
①现态:是指当前所处的状态。
②条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
我们可以用状态表了表示整个过程,如下图所示。
 


状态表
这里需要注意的两个问题:
1、避免把某个“程序动作”当作是一种“状态”来处理。那么如何区分“动作”和“状态”?“动作”是不稳定的,即使没有条件的触发,“动作”一旦执行完毕就结束了;而“状态”是相对稳定的,如果没有外部条件的触发,一个状态会一直持续下去。
2、状态划分时漏掉一些状态,导致跳转逻辑不完整。
所以维护上述一张状态表就非常必要,而且有意义了。从表中可以直观看出那些状态直接存在跳转路径,那些状态直接不存在。如果不存在,就把对应的单元格置灰。 每次写代码之前先把表格填写好,并且对置灰的部分重点review,看看是否有“漏态”,然后才是写代码。QA拿到这张表格之后,写测试用例也是手到擒来。
2、状态机在object-C的代码实现。
我在开发百度地图导航过程页以及百度CarLife的反控手机识别中都用到了有些状态机编程,下面我结合个人的经验,给大家分享一个iOS程序中实现有限状态机的写法。
先回顾一下上面那个状态表,其中状态变迁时执行的动作,可能是由一系列的元动作组成,并且通常都是跟现态和次态强相关的,所以,我把状态表做一个改进,如下所示:
 


其中:FSM_FUN(stateA,stateB) 就表示,从状态stateA跳转到stateB时要执行的所有元动作的有序集。
1、准备工作,状态定义和事件定义


宏定义
这里没有啥特殊的,主要是借助宏定义,比较巧妙的实现枚举值到字符串的转换,比如枚举值stateA,能自动生成字符串@“stateA”,用于后面的状态函数名拼接。这是一个通用的枚举值自动转字符串的解决方案,参考的链接( http://stackoverflow.com/a/202511)
2、Model类定义
iOS开发都会采用MVC架构或者相关变种,但是状态的维护都会实现在Model中。这里定义了一个简单的TestModel,它有一个成员变量state,保存着当前的状态。


Model定义
3、实现Model类的一个category,
里面主要定义和实现了状态跳转时要执行的一些动作。


4、重新Model的setState方法,使得在设置状态时能自动去执行状态跳转时需要执行的动作。


5、处理事件输入,实现状态跳转逻辑。
这里有两种写法,一种是在状态中判断事件:


状态中判断事件
一种是事件中判断状态:


事件中判断状态
思考与讨论:
状态跳转逻辑的两种写法,实现的功能和效果完全相同,孰优孰劣,欢迎留言探讨。
本人观点:一般业务场景来说,状态的数量是确定的切数目较少,不同状态下需要处理的事件也不一样。而触发的事件数量则比较多,采用上面第二种方式在事件中判断状态也有利于把里面一层的switch/case剥离出来当成单独的函数,做一些代码模块结构的优化,故推荐使用第二种方式,事件中判断状态
优化后的状态变化函数代码,如下图。


优化后
欢迎探讨
本文主要介绍了一下什么是有限状态机,然后通过一个具体的代码示例介绍了一些本人在状态机编程上的经验和理解,欢迎各位进行交流指正。
谢谢大家的宝贵时间。
微信公众号:云峰小罗,分享 编程.生活.段子
 

http://weixin.qq.com/r/bkXr8zjEkmXtrXyQ9xB8 (二维码自动识别)

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

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

相关文章

wince 环境变量

wince工程的环境变量在PBInitEnv.bat文件中存储,经测试,如果在下面增加了新的变量,在此文件中会出现

【转】vs平台工具集介绍,vc6~vs2019各IDE对应的工具集版本

转自:vs平台工具集介绍以及安装 - jack_Meng - 博客园 一、什么是平台工具集: 平台工具集其实是MSBuild其目录所在C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0。VS从2010之后开始支持使用之前的版本进行编译,可以在工程属性->常…

基于FPGA的前向纠错算法

目前,无线产品的广泛应用使无线音频和视频的高质量传输成为可能。蓝牙、无限局域网等无线传输设备比较复杂,成本较高,急需 开发一种简便的、仅用于流媒体的无线传输平台,将音频数据实时地发送到移动终端。由于音频数据的实时性&am…

【转】Windows版本,OS内核版本,Windows SDK之间的关系

转自:Windows版本,OS内核版本,Windows SDK之间的关系 - 知乎 前言:我们经常会会被几个概念弄混淆,什么是Windows版本号,什么又是操作同内核版本,开发C的时候什么又是WindowsSDK,实际…

【转】30分钟学会UML类图

转自:30分钟学会UML类图 - 知乎 30分钟学会UML类图 肖继潮 UML图有很多种,但是并非必须掌握所有的UML图,才能完整系统分析和设计工作。一般说来,在UML图中,只要掌握类图、用例图、时序图的使用,就能完成大…

Microsoft SQL Server 2005数据库安装

Microsoft SQL Server 2005数据库,电脑里原有的mssql2000已经不适用了,到网上寻找SQL Server 2005简体中文开发版的下载地址,一开始下载了个学习版的express,可限制太多,还是决心安装开发版本的。到微软的官方网站寻找…

Wince6.0 cleartype

WinCE6.0下显示宋体毛刺很严重,影响显示效果,打开cleartype以后字体显示平滑,但是不知道为什么wince桌面上的中文字体显示乱码,而且自己的引用程序也变的很卡。 开始以为是字库的原因,后来添加了系统的组件以后一切正常…

【转】ubuntu16.04安装配置tftp服务

转自:ubuntu16.04安装配置tftp服务_carspiriter的博客-CSDN博客_ubuntu安装tftp 首先声明:tftp是client客户端,tftpd是server服务器端,d应该指的是daemon。如果你要从别人的tftp服务器端上传/下载东西,就要用到tftp&a…

【转】Dicom中的Image Orientation/Position的理解

转自:Dicom中的Image Orientation/Position的理解 - 知乎 在DICOM中,是通过Image Position和Image Orientation来描述当前的图像和人体坐标系的相对位置的。 打开DCM文件时,会发现下边的两个tag (0020,0032) DS ImagePosition(Patient) &q…

【转】矩阵变换坐标系 深入理解

转自:矩阵变换坐标系 深入理解 - 知乎 网址链接:从坐标系图中理解“空间变换” 小谈矩阵和坐标变换 矩阵坐标系变化理解 让我们从一个实际的例子入手:下图是一个用两维的笛卡尔坐标系表示的二维空间。 其中,黑色坐标系 x-y代表…

【转】坐标系变换矩阵推导

转自: 坐标系的变换矩阵推导 1.平移变换 假设存在点(x,y,z),将x移动a,y移动b,z移动c,到新的点(x′,y′,z′),则: 中间4x4的矩阵叫变换矩阵。可见,如果要平移坐标,要将坐…

【转】图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵

转自:图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵_sherlockreal的博客-CSDN博客_视角矩阵 图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵 图形流水线中坐标变换过程模型矩阵:模型局部坐标系和世界坐标系之…

【转】C#开发PACS医学影像处理系统(二):界面布局之菜单栏

转自:C#开发PACS医学影像处理系统(二):界面布局之菜单栏 - 乔克灬叔叔 - 博客园 在菜单栏布局上,为了使用自定义窗体样式和按钮,我们需要先将窗体设置为无边框,然后添加一个Grid作为菜单栏并置顶,Vertical…

WF4.0 基础篇 (二十九) WorkflowInspectionServices

本文例子下载: http://files.cnblogs.com/foundation/WorkflowInspectionServicesSample.rar WorkflowInspectionServices 类 WorkflowInspectionServices可以得到流程中的Activity, 由于WF4.0的ActivityTree相对复杂,并不是象WF3.X的结构那样清晰, 在WF4.0中Activi…

【转】C#开发PACS医学影像处理系统(三):界面布局之工具栏

转自:https://www.cnblogs.com/Uncle-Joker/p/13650330.html 工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中 Style"{StaticResource ButtonStyle}&…

WinCE6.0 修改开机Logo方法

中秋假期已过,回来继续该博文主题。今天讲解第二种方法,将 Logo 图片的数据写入到 Nand Flash 中,在启动初始化 LCD 的时候,从固定的地址将数据读出并填充到显示缓存中。实验平台:WinCE6.0Android6410 4.3寸CLD。以下内…

【转】DICOM开发工具总结

转自:DICOM开发工具总结_qimo601的专栏-CSDN博客 网上流行的DICOM协议开发工具: 1、DICOM开发类库主要有: (1)DCMTK(3.6.0), 官方下载网站,(如何安装编译DCMTK3.6.0) DCMTK实现了对DICOM图像…

【转】CT中的“层“与“排“的区别

转自:CT中的"层"与"排"的区别 自从离开医院,专业培训磁共振,有差不多5年时间没有接触CT了。影像技术及影像医学诊断说到底是一门经验技术累积学科,这种学科的特点就是熟能生巧,几年不碰&#xff0…

修改SMDK6410的调试串口为普通串口(wince系统)

环境: 飞凌OK6410A开发板, Windows CE6.0系统 最近在做GPRS通信,可是手头上的GPRS模块(Q2403A)是五线串口的(RXD、TXD、GND、RCS、CTS),老板又不愿买新的模块。所以考虑将调试串口CO…

【转】CTA图像

转自:CTA图像 CT检查在临床中应用十分广泛,CT以其扫描速度快,对骨头及钙化敏感而具有部分优势。 CTA是CT血管成像,是CT临床应用中一个非常重要的部分,由于血管及其背景软组织自然对比差,常规CT平扫往往难以…