深入浅出理解有限状态机

news/2024/7/20 20:58:22 标签: iOS, 状态机, MFi, MFi认证

有限状态机

有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。比如下图非常有名的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剥离出来当成单独的函数,做一些代码模块结构的优化,故推荐使用第二种方式,事件中判断状态

优化后的状态变化函数代码,如下图。

优化后

欢迎探讨

本文主要介绍了一下什么是有限状态机,然后通过一个具体的代码示例介绍了一些本人在状态机编程上的经验和理解,欢迎各位进行交流指正。

谢谢大家的宝贵时间。

微信公众号:云峰小罗,分享 编程.生活.段子

本人维护了一个“MFi开发交流”的微信群,里面有iOS开发 、外设驱动、MFi认证等各类相关人员,大家相关交流,互帮互助。

想进群的可以加本人微信:luoxub ,备注:MFi, 邀请进群。


http://www.niftyadmin.cn/n/1080905.html

相关文章

虚拟旅游 宅人新爱

这是虚拟旅游网站中的卢浮宫,你看出来了吗?   只要轻点鼠标,就可逛逛卢浮宫,爬爬阿尔卑斯山……通常不用半小时,就可从故宫游到白宫,这便是当下最热的虚拟旅游。   跟护照说byebye,也无需担…

哇擦,传说中的堆栈溢出和快速排序

stack overflow 堆栈溢出和快速排序这两个概念对开发人员来说并不陌生,但是通知都只是听说过,真正开发过程中却很少会遇到。我也是敲代码好些行后非常有幸撞上了,而且还是两个一起出现的,这其中过程的滋味还是相当酸爽&#xff0…

关于MFi认证你所必须要知道的事情

前面我写了一篇文章《iOS App连接外设的几种方式》,其中EAP和NCM是都需要做MFi认证。对于苹果的MFI认证,对iOS开发的同学来说其实是一个比较陌生并且繁琐的topic,因为网上资料确实很少,百度Google几乎都查不到啥资料,而…

一些移动领域内,我们应该知道的小知识点

手机上网的IP是运营商ISP自动分配的,每次上网运营商ISP都会选出一个空闲的IP给你,以保证你手机的IP在同一个时间里不会和其他手机相同。但这些IP是属于运营商基站的网内IP。手机上网有点像公司内网上的电脑通过网关服务器上网。对外界,所有的…

iOS App连接外设的几种方式

一般iOS开发者做APP开发大部分时候都是通过Http(s)请求跟后台服务器打交道,做一些信息展示和用户交互。很少涉及到去跟外部硬件设备连接的开发。随着近年来车联网和物联网的兴起,智能家居和智能硬件的逐步火热,越来越多的app被开发出来&#…

《当程序员的那些快乐日子》(十三)程序员,你有什么牛逼的?

记得还是大学生的时候,第一次去公司实习,和老大侃大山,讨论软件行业的局面,老大给我说:“软件行业,其实TMD就是一个服务行业”。我恍然大悟,确实啊,软件行业就是一个服务行业。我以优…

大龄程序员的出路在哪?程序员中年危机怎么办?

《都挺好》最近在热播,上面这段对话引起了很多程序员的共鸣。 其实年龄问题只是一方面的问题,即使现在年龄不大,也会面临很多的不稳定因素,比如百度推出高管退休计划,腾讯宣布裁减10%的中干,阿里大文娱也开…

根据自己的理解给出人工神经网络的定义,并指出其特征

人工神经网络的基本组成是什么啊 基本结构是三层,输入层,隐层,输出层,各层由神经元和神经元之间的权值组成。 人工神经网络的定义,详细说明 人工神经网络(Artificial Neural Networks, ANN)&…