1. 简单介绍状态机java
2. 状态机的本质redis
3. 状态机应用场景spring
状态机由状态寄存器和组合逻辑电路构成,可以根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动做、完成特定操做的控制中心。以上是百度百科对状态机的解释。springboot
在百科的解释中,咱们能够提炼出状态机的几个要素:存储状态,逻辑电路,预先设定的状态转移路径,外部来的信号,内置的特定操做等。由这些关键要素咱们能够推断出如下几点:并发
状态数据有预先设定的多种值app
逻辑电路是完成内置特定操做的基础“代码“(基础设施),由工程司开发spa
状态能在多种值之间转移设计
每次转移都由外部信号触发code
状态转移触发后,会有相应的内置操做
由以上这些特性共同构成了一个独立的控制中心,并且这个控制中心与外部各类信号是低耦合的,全部外部信号都要接入一个共同的控制中心,最终也由控制中心完成信号的后续流程。
在java开发中,状态机FSM(有限状态机)是一种常见的设计模式,经常用于一些复杂的业务场景,解决繁琐杂乱的if...else...代码段。
“Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.“
-对象内部状态不一样会有不一样的行为。彷佛好像是不一样的类同样。
以电梯为例,电梯有4种状态:开门、关门、运行、中止。电梯的动做:开门、关门、运行(上升或降低)、中止(悬停不动)。
Col1 | 开门行为 | 关门行为 | 运行行为 | 中止行为 |
---|---|---|---|---|
开门 态 | ❌ | ✔ | ❌ | ❌ |
关门 态 | ✔ | ❌ | ✔ | ✔ |
运行 态 | ❌ | ❌ | ❌ | ✔ |
中止 态 | ✔ | ❌ | ✔ | ❌ |
开门状态下,电梯只有关门行为
关门状态下,除了关门行为其余行为都有
运行状态下,只有中止行为
中止状态下,有开门行为和运行行为
状态图以下:
状态机设计模式的好处:
下降程序的复杂度;
提升程序的可维护性;
状态机模式体现了开闭原则和单一职责原则。
每一个状态都是一个子类,增长状态就要增长子类;修改状态只要修改一个类就好了。
这种设计模式将每一个状态的变动后的处理逻辑都作了统一封装,跟业务代码耦合,只接收相互约定的信号(事件)。
由状态机的几个要素咱们也能够知道,在一个复杂的业务流程过程当中,有多种数据状态,多种处理动做,以及多种维度的角色。在这样复杂业务场景下,若是只是简单使用if...else...语句,首先可读性就很是差,并且维护起来很是困难,甚至是开发人员都没办法理清楚本身写的if..else语句。若是复杂的业务流程有了变动和新增,那这个维护起来就是个灾难,各类复杂问题不得而知。就像下图同样
用if..else..代码来开发复杂的业务流程,会面临下面几个问题:
复杂的业务流程,if.else代码几乎没法维护
随着业务的发展,业务过程也须要变动及扩展,但if.else代码段已经没法支持
没有可读性,变动风险特别大,可能会牵一发而动全身,给服务带来S级风险。
其余业务逻辑可能也会跟if.else代码块耦合在一块儿,带来更多的问题。
这时候,状态机就是个很是好的解决方案,能有效地解决这些问题。
一个状态机定义之后,在某个状态下就只接收固定的Event,也就是执行指定的操做,这样流程就能按照预期定义的那样流转,不会出现乱入的状况,执行了一些在某状态下不容许执行的操做,也就是说,状态的流转都是在控制范围,不会超出预设的状态空间。
状态机创建的控制中心是跟外界低耦合的,经过event通讯。
控制中心全部的状态都是预设好的,不会超预料。
状态的跳转都是有设定控制条件的,会按照预设的转移路径运动。
状态机还很是容易的扩展和变动,支持因业务的发展而变动或扩展复杂业务流程
状态机典型的应用有工做流引擎,游戏中人物状态变化引擎,订单交易等。前两种很是复杂,下面我就简单以订单交易这个场景来聊聊状态机的应用场景以及基于spring statemachine的项目。
配置pom依赖:
<dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-core</artifactId> <version>2.1.2.RELEASE</version> </dependency>
状态枚举和事件枚举:
/**
* @author Batman create on 2019-05-07 14:59
* 状态枚举类
*/
public enum States {
/*
待支付
*/ UNPAID, /* 待收货 */ WAITING_FOR_RECEIVE, /* 结束 */ DONE, /* 退货中 */ WAITING_FOR_GOODSBACK } /** * @author Batman create on 2019-05-07 15:00 */ public enum Events { /* 支付 */ PAY, /* 收货 */ RECEIVE, /* 退货 */ GOODS_REJECTED, /* 退款 */ REFUND }
欢迎加入技术群:得到更多java,springboot,redis,kafka圈的好友,共图技术将来
还要配置状态转移信息以及事件处理器逻辑的开发。完整的demo项目,请关注公众号"前沿科技bot"并发送"状态机"获取。