java之状态机图

引子

第一次听到这个词时,我是有点奇怪的。什么是状态机呢?

考虑一个场景,在前面的用户登陆的时序图中

java之状态机图

有一步是检查用户的合法性,这里面可能包括用户的账号的状态正常/异常。

那么,用户的状态可能有哪些呢?状态又是如何流转的呢?

找出可能的状态

假设用户状态为status,模拟一下用户在系统中的整个流程

  • 用户注册开始,输入注册信息(包括邮件地址);系统插入一条用户记录,状态为UNACTIVED;发送一封确认邮件到用户邮箱
  • 用户收到邮件,点击确认,更新状态为ACTIVED,注册成功
  • 用户异地登陆,系统监测到用户账户疑似被盗,紧急冻结,状态变为FROZEN
  • 用户申请解冻,状态又变为ACTIVED
  • 用户注销账号,状态变为CLOSED

用户状态找出来了,用图表示一下

java之状态机图

但是这样光秃秃的几个状态是没有什么意义的,尝试着将它们串联起来

java之状态机图

这样,似乎完成了一个简单的状态机。约定在首尾加上开始,结束符号。

但是有2个问题:

  1. 上面的状态机是按照每个状态推进的,会不会有其它状态推进的路径呢?有可能,比如用户**后直接注销java之状态机图
  2. 上面的状态机都是正向推进的,有没有可能逆向的的?也有可能,比如设计成注销之后还可以再**java之状态机图

状态机

一般用状态机图来表示单个对象的生命周期。也属于动态建模的一种。

理论上除了各种状态之外,还有一个初态节点

java之状态机图

终态节点

java之状态机图

及各个节点转换的转接关系,即箭头连线+上面的条件(发生状态转换时,对应的条件必须为真)

java之状态机图

子状态

上面的状态如果要定义的更细一点(只为说明,不是真实案例)

  • 发送邮件成功,状态更新为SEND_MAIL_S
  • 发送邮件失败,状态更新为SEND_MAIL_F
  • 用户**失败,状态更新为ACTIVED_FAILED
  • 用户**成功,状态更新为ACTIVED

状态机可能为

java之状态机图

可以发现,**态的看起来有点复杂,用子状态来表示下

java之状态机图

应用场景

状态机除了业务需求之外,有2个地方比较有用

  • 设计模式中的状态模式
  • 可以用作接口幂等