状态机,又称有限状态自动机(Finite State Machine,FSM),是现实事物运行规则抽象而成的一个数学模型。它由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。
状态机主要分为两大类:第一类,若输出只和状态有关而与输入无关,则称为 Moore 状态机;第二类,输出不仅和状态有关而且和输入有关系,则称为 Mealy 状态机。
我们以汽车的变速箱来当做状态机来举个🌰例子,如果是自动挡的变速箱,那么变速对应的每个档位就一个状态,如P档是表示停状态、N档是发动起空转状态、D 档是行驶状态、R 档倒车状态。而每一次的换挡行为就都会改变变速箱的状态,这个换挡行为就相当于状态的状态转换事件。状态机的状态转换事件都会有限制,而变速箱上的状态转换限制是物理限制,以我雪佛兰为例,从P档转换到D档,需要从 P 档 -> N 档- > R 档 -> D 档按顺序转换,不能直接从 P 档转到D档。
确定状态:明确系统的各个状态,变速箱的各个档位就相当于状态机的状态。
确定转移:定义状态之间的转移,并确定在满足什么条件时进行转移。在变速箱上面每次换挡都是一次状态转移。
定义动作:针对不同的状态,定义对应的动作,这些动作可能是在进入状态时进行,退出状态时进行,或者在特定转移时进行。
事件:也可以叫做 Trigger,表达的意思都一样,就是要执行某个操作的触发器或口令:当状态机处于某个状态时,只有外界告诉状态机要干什么事情的时候,状态机才会去执行具体的行为,来完成外界想要它完成的操作。
了解基础知识后,再画出状态图,就可以按照状态图来写代码去实现这个状态机的逻辑了
在前面的章节里面我们介绍了什么是状态机,和怎么使用状态机。在开发的日常开发中,我们总会有这样的思考,状态机的代码那么复杂,复杂的代码可能拖慢了我们的开发进度,我们有必要使用状态机吗?那么这里面我们就来分析下状态机可以给我们带来什么,而又有哪些不好的地方。
总的来讲就是状态机是使用起来的时候是方便的,也有利于后期维护和扩展,但是使用成本比较高,技术上对程序员有一定的门槛。但是这些都是从技术上来讲的,如果从其他的维度来看会不会有些不同呢?
前面说了状态机的优劣,都是以技术的角度去看的。然而如果换一个从业务的角度来看状态机可以带来什么。
领域驱动设计是软件开发的一种方式,问题复杂的地方通过将具体实现和一个不断改进的核心业务概念的模型连接解决。这个概念是 Eric Evans 提出的,关于领域驱动设计的定义,Glossary of Domain-Driven Design Terms,网上有很多这里就不详细介绍了。
前面我们聊了状态机,现在又突然跳到 DDD(领域驱动设计)这两个有什么关系,这里就有必要说下DDD里面的一种开发思想就是让领域专家和技术专家建立共同的语言去一起开发一个系统。而状态机刚好是把这个业务流程,用技术上的语言表达出来,这样技术专家和领域专家会有一个通用的模型是去描述各自要表达的思想,从而更好进行沟通和开发。
对于状态机出来说除了可降低领域专家和技术专家的沟通成本,并且在辅助领域模型设计方面还有以下几点帮助:
对于状态模式辅助 DDD 的设计这个方面来说,状态机的一些概念和 DDD 里面的一些概念是有些相似的。对于一些刚接触 DDD 的人来讲,通过先分析一个业务的状态模式,然后再以状态模式去用 DDD 的思想设计系统是有些帮助的。从这个方面来讲状态模式是可以帮助新人去理解 DDD,降低一些 DDD 入门的门槛。但是如果要用好 DDD 的话,光靠状态模式是远远不够的,DDD 是一套完整的软件设计的方法论,而状态机只是状态模式的一种实现。
状态机的入门有一定的门槛但不是太高,在使用前最好是听取下经验的技术人员建议再确定是否使用状态机,如果给一点具体建议的话个人感觉需要考虑以下几点:
状态机作为一种设计模式,除了在技术上可以让我们的代码变动更加的灵活和易于扩展以外,它更大的优点是在可以在做技术分析的时候让我们更加清晰地理解整个业务流程。个人觉得在项目中是不是要使用状态机不是重点,重点是使用状态机的思想去分析业务流程,只要能清晰的理解业务流程,不管用什么方式去实现这个业务都会是事半功倍的。