简单实用的状态机设计与实现

16,134 阅读2分钟

finite-state machine 有限状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学计算模型,被广泛用于建模应用行为、硬件电路系统设计、软件工程,编译器、网络协议、和计算与语言的研究。

状态机的出现是为了将复杂对象的状态变化进行建模,采取工程化的方式来处理,方便理解与沟通

状态机引入

在实际开发中,也会经常遇到状态机的问题。举个简单的例子,考虑用户支付场景下订单的状态,订单状态可能经过这样的变化:待付款 --> 处理中 --> 失败/成功 在这个过程中,业务系统需要向第三方支付系统(微信、支付宝)查询订单状态,更新本地库的订单状态。

类似的场景很多,特别是在对象的状态比较多的时候,就变得越来越难以维护,同时还伴随这并发问题,一不留心就会出错。所以设计一个通用的状态机管理器就很有必要了。

状态机设计

一个良好的状态机设计,首先要有很好的通用性,能够适应很多场景,其次对于开发者友好,不用开发者关心内部实现。

由状态机的定义可知,状态机由状态转移组成,每一个状态转移包含前置状态、行为操作、后置状态组成,通常状态改变时还伴随着事件通知。

状态机实现

状态机的实现也不难,由一下几个类组成

  • StateManager :状态管理器,状态机主要逻辑的实现者,本身是一个抽象类,维护一组自动状态转换(非终态 --> 终态)和 一组状态改变监听器
  • StateTransition : 状态转换,定义了前置状态(preState)、行为操作(operation)、后置状态(operation返回值)
  • StateListener :状态变化监听器
  • StateAutoSync :状态自动同步器,内部注册所有的状态管理器,负责找到对应的状态管理器,进行状态的同步

StateManager子类实现主要有两类 LocalStateManager (内存维护状态) 和 GlobalStateManager (全局存储维护状态,如mysql/redis)

异步事件驱动

增加事件驱动,支持异步(线程池 并发)和同步两种模式

整个处理过程大致为:处理请求作为事件进入系统,由异步调度器(AsyncDispatcher) 负责调用相应的事件调度器(Event Handler)。该事件调度器处理完毕后可能会产生一个新的事件交由调度器进行分发,也可能该调度器本身就是一个有限状态机,内部处理状态的转移。

具体代码详见:github.com/VectorJin/S…