什么是状态机?
做产品的时候,我们总能遇到一些比较复杂的逻辑问题,而普通的流程图,或时序图对于对象和状态的解读缺乏直观的描述。
这时,推荐使用简单的状态图来对逻辑问题进行描述。
在开发过程中,如果有逻辑关系比较混乱的,我们就可以考虑使用有限状态机来解决问题。
状态机,表示某几种状态之间的切换。描述一个对象从一个状态,经过一个事件驱动转变为另一个状态的过程,叫做一次状态迁移,一个对象所具备的所有状态迁移过程叫做状态机。
因为状态机的状态是有限的,所以一般上也叫有限状态机(Finite State Mache)。
有限状态机,(英语:Finite-statemachine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。
有限状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在
它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。在计算机科学中,有限状态机被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。
状态机的作用
利用状态机可以精确地描述对象的行为,从对象的初始状态起,开始响应事件并执行某些动作,这些事件引起状态的转换,对象在新的状态下又开始响应状态和执行动作,如此连续进行直到终结状态。
1、不需要每个接口都校验当前状态:直接数据库配置某个状态,加某个操作,才能进行下去,如果不对的状态进行该操作,会报错
2、同一个接口配置不同的流程:同一个如审批通过的接口,不同状态下审批不通过,需要走不同的流程,如审批中审批不通过,走改变状态的流程,变更审批中审批不通过,走回退历史的版本数据的流程,如果不用状态机,则需要分开写2个接口,或者在一个接口里走if else,考虑到复杂的订单状态变迁触发节点,可能if-else会非常多,比如某5种状态下的同一个接口走不同的流程
3、实现流程可配制化,高内聚,集中配置,直接在数据库更改配置信息,可维护性和扩展性强
4、易变更,快速修改
5、易使用,极大简化前端的代码,是否可以删除,变更按钮的显示和隐藏通过后端返回
状态机由什么组成?
状态:表示一个模型在生存期内的状况
转换:表示两个不同状态之间的联席
事件:是在某个时间产生的
活动:是在状态机中进行的一个非原子的执行,有一系列动作组成
动作:是一个可执行的原子计算,它导致状态的变更或者返回一个值
如何画状态图?
当需要描述一个对象或系统的行为状态时,相比于直接的语言描述,更推荐使用状态机表或状态机图的形式。
首先看一下图形中的基本元素:
分析需求时需要了解以下六种元素:
起始
终止
现态
次态(目标状态)
动作
条件
这样,我们就可以完成状态机图了,来看一个具体的案例吧:
1.现态:是指当前所处的状态。
2.条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
3.动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
4.次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
注意:
1、注意区分“程序动作”和“状态”。如何区分“动作”和“状态”?
“动作”是不稳定的,即使没有条件的触发,“动作”一旦执行完毕就结束了;
“状态”是相对稳定的,如果没有外部条件的触发,一个状态会一直持续下去。
2、状态划分避免缺漏,这样会导致跳转逻辑不完整。查看状态图或者状态表是很有必要的,尽量让设计方案足够完善。
如何做状态机表?
先看案例,下面的状态机图展示了一个文件的状态流转。
将状态图转为状态表有多种制表法,如果以纵坐标区分,有两种:
左边的状态表的纵坐标为初始状态,横坐标为终止状态。
右边的状态表的纵坐标为动作条件,横坐标为终止状态。
如果动作多且复杂的情况下,建议采用右侧表格方式,会更清晰。
状态机图的使用场景
状态机图常应用在程序的设计过程中,使用清晰明了的状态机图设计代码逻辑架构,再使用编程语言去实现。
也可以画一个状态机图来展示某岗位的工作:
开发实现状态机的设计实例
实例:电商平台订单状态设计
状态机的技术实现
首先会有2个表:flow和flow_picker表:
flow表:主要用于存放不同的流程的名字,主要会有个id,订单走一个流,退货单走一个流
flow_picker表:主要是每个业务创建的时候,会关联到哪个flow,就是关联到哪个流程id里,会通过来源,渠道,类型,等级等等条件,筛选出这个订单,关联的flow,存入订单表里的flow_id字段
配置流程的表:
先会根据订单的flow_id筛选出走哪个流程,再根据来源状态 source_status,操作operation_value,到达目标状态target_status,执行action_name,
action_name是自己配置的,action_name里面的类就是不同流程,执行的代码
根据这个配置,初始化时注入所有的action,可以调到数据库对应的配置的aciton类,同一个接口,可执行多个流程就完成了。
网友评论