引子
第一次听到这个词时,我是有点奇怪的。什么是状态机呢?
考虑一个场景,在前面的用户登陆的时序图中
有一步是检查用户的合法性,这里面可能包括用户的账号的状态正常/异常。
那么,用户的状态可能有哪些呢?状态又是如何流转的呢?
找出可能的状态
假设用户状态为status,模拟一下用户在系统中的整个流程
- 用户注册开始,输入注册信息(包括邮件地址);系统插入一条用户记录,状态为UNACTIVED;发送一封确认邮件到用户邮箱
- 用户收到邮件,点击确认,更新状态为ACTIVED,注册成功
- 用户异地登陆,系统监测到用户账户疑似被盗,紧急冻结,状态变为FROZEN
- 用户申请解冻,状态又变为ACTIVED
- 用户注销账号,状态变为CLOSED
用户状态找出来了,用图表示一下
但是这样光秃秃的几个状态是没有什么意义的,尝试着将它们串联起来
这样,似乎完成了一个简单的状态机。约定在首尾加上开始,结束符号。
但是有2个问题:
- 上面的状态机是按照每个状态推进的,会不会有其它状态推进的路径呢?有可能,比如用户激活后直接注销
- 上面的状态机都是正向推进的,有没有可能逆向的的?也有可能,比如设计成注销之后还可以再激活
状态机
一般用状态机图来表示单个对象的生命周期。也属于动态建模的一种。
理论上除了各种状态之外,还有一个初态节点
终态节点
及各个节点转换的转接关系,即箭头连线+上面的条件(发生状态转换时,对应的条件必须为真)
子状态
上面的状态如果要定义的更细一点(只为说明,不是真实案例)
- 发送邮件成功,状态更新为SEND_MAIL_S
- 发送邮件失败,状态更新为SEND_MAIL_F
- 用户激活失败,状态更新为ACTIVED_FAILED
- 用户激活成功,状态更新为ACTIVED
状态机可能为
可以发现,激活态的看起来有点复杂,用子状态来表示下
应用场景
状态机除了业务需求之外,有2个地方比较有用
- 设计模式中的状态模式
- 可以用作接口幂等