1、 基本概念
1.1 状态
状态:是事物的一种属性,指事物表现出来的行为和形态。对象状态是指对象或所属类的的所有属性的当前值
1.2状态机
状态机图即为状态机,实质上是由一种由状态、转移、事件和动作组成的状态机。它描述了一个对象在生命周期内所经历的各种状态,状态之间的转移,发生转移的动因、条件以及转移中所执行的活动。
状态机可归纳为4个要素,即现态、条件、动作、次态。“现态”和“条件”是因,“动作”和“次态”是果。
①现态:是指当前所处的状态。
②条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
③动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。
④次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。
1.3 状态的转移
一个处于源状态的对象当满足一定条件时,会执行相应的动作,然后进入目标状态。可以从一个状态发出一个或多个状态转移,前提是转移要唯一。
自转移
源状态和目标状态相同,所包含的动作和事件 与 转移 完全相同。不改变对象状态,只导致对象状态的中断
内部转移
在不离开一个状态的情况下连续执行多个动作的情形称为内部转移
1.4 判断与决策点
表示工作流基于监护条件将出现分支的位置
1.5 事件
指示状态之间发生变化的条件,可以是内部事件(如异常)也可以是外部事件;可以是同步也可以是异步事件
- 调用事件:同步,代表一个操作的调用
- 信号事件:异步,信号是对象异步发送并由一个对象接收的具有名字的对象。比如:消息
- 变化事件:是状态中的一个变化或者某些条件满足的事件,一般用when表示
- 时间事件:经过一定时间或达到某个绝对时间后发生的事件(如task)【绝对】
- 延迟事件:延迟响应直到某个合适的时刻才执行(如ScheduledThreadPoolExecutor)【相对】
无论异步还是同步,特别是对异步状态机而言,状态机内部不能在某个状态发生等待、阻塞等情况,而应该是标记状态后返回,把执行的机会让给其他任务或逻辑体。之后条件达到的情况下,通过事件分发机构调用状态机的运行。
2. 状态机的好处
古老的状态图的代码实现是通过 if-else或swich实现,但是这种方法代码太过复杂,逻辑不清晰,可读性较差,而程序本身没有保持自身持续运行的必要性。所以当一个状态的扭转有多个分支时,应该使用状态机。每个状态当得到事件的触发时会产生相应的行为,状态发生变化。所以状态机 降低了程序的复杂度、提高了可读性。
2. 状态机的使用
2.1 设计状态
状态是指在对象的生命周期中满足某些条件、执行某些活动或等待某些事件的条件。根据业务场景找出所有会出现的状态,一般情况下当一个状态的扭转出现多个分支时,则可以把这个状态设定为其中的一个状态机
2.2 状态迁移路线
有了状态表后,确认状态的迁移路线,不能跨状态迁移
2.3 重新整理状态表
绘制状态机图时,需要将状态设定在合理的位置,然后使用之前的状态迁移路线连接,这一步相当于是前两步的综合,不过很重要,最终的图示以这个为准,合理的状态布置除了便于理解之外,还利于代码的编写。
2.4 1️以状态的迁移作为事务的边界
在分布式系统中,如何保证事务问题,可以根据状态机的扭转来作为事务的边界,在一个状态迁移里的一系列行为应该保证事务一致(失败重试 | 失败回滚 | 其他)。可以对流程进行拆分,把一个状态迁移拆分为一个小流程,在这个小流程里事务一致,如果不根据状态的迁移拆分小流程,那在这个大流程里多个子业务流程的事务机制为一个,可能每个子流程的事务机制是不一样的(失败重试 | 失败回滚 | 其他)。并且实际上每一个条件满足或事件发生时只会有其中的一个小流程会执行