redis读写分离代码怎么写_怎么写状态变更的代码?

6254db3048d656194d981241244c193c.png
在日常开发中,你是否会遇到过“状态流转”的代码?例如订单状态的变化流程,从“提交”到“支付”,“配送中”,“收货”。怎么写这些代码才能够易于维护和扩展?使用状态模式和Spring的状态机或许能帮助你。来看看这篇文章,应该有所收获。

在下手写代码前,估计你会画一张状态变更的“流程图”(或者叫有限状态机),本文假设一个交易需要经过的状态如下:【初始化->草稿->等待审批->取消或者完成】

23622b39dfb45101accfb192c461102e.png
每个绿色框代表一个“状态”(State),每个箭头代表一个“事件”(Event)。一个状态经过一个事件能确定到达另外一个状态。

在没有了解状态模式之前,设想一下,我们会怎么写代码,可能会把所有的事件写在一个大的switch里,然后根据不同的状态进行不同的处理,这样我们在修改状态的业务逻辑或者增加状态的时候,需要修改同一个switch下的代码,然后进行回归测试,类似以下:

private 

稍微改进一下,单独为每个事件实现一个方法,类似以下:

private 

这样写每个事件相对独立,不过要新增事件和状态的时候需要新增方法,之后进行回归测试。并且这两种写法都有同样的问题,状态的变化与业务逻辑纠缠在一起,并且状态变化流程并不清晰,如将来需要增加新的状态,将难以扩展。例如我们现在需要需要增加一个“等待验证”的状态(如下图红色部分),我们得把真个流程的代码都小心理解透了,才知道在哪里“塞”进去这一块。

8767de4f9116ae0c850215346f8b3e45.png
如何增加一个状态?

看看“状态模式”是如何帮助我们的:

f036ae02b6e9989a73aaee138e8a164e.png
状态机接口-MachineState 一个状态一个类,继承MachineState,状态机类StateMachine

首先有一个状态机状态接口(MachineState),包含每个状态都有的抽象方法(processBusinessLogic),每个状态都是一个类,实现MachineState的抽象方法。这样使每个状态解耦,新增一个状态也不必修改原有的代码(符合开闭原则)。另外一个状态机类(StateMachine)负责持有这些状态的聚合并且负责状态的变更流转,把状态变更和业务代码做解耦。这样说毕竟苍白,来看看代码怎么写:

public 

我们平时在做web开发的过程中,保证每次请求都是“无状态”(stateless)的很重要,可是状态机的运转是要保证有状态的,怎么做到状态机的持久化?如果遇到多线程的状态要处理怎么办?幸好Spring Statemachine项目都为我们想好了。先从最简单的实现状态机开始:

步骤一:配置spring状态机

@Configuration

步骤二:配置监听器,每个事件触发的业务逻辑写在这里

@Component

步骤三:启动spring进行测试

@SpringBootApplication

在实际项目中,需要持久化状态机的状态,可以使用mysql或者redis来存储。文中的所有代码都已经上传到github,以下是项目链接:

chenkaijiekidd/state-machine​github.com
2da8699628a21b7e4a410ef7e57e560b.png

Spring statemachine的项目地址:

Spring Statemachine​projects.spring.io
4a93e40391c9f676fbe1bbdfb4e37471.png

希望这篇文章能帮助你,有任何疑问可以评论,我也会一一回答。Spring Statemachine希望这篇文章能帮助你,有任何疑问可以评论,我也会一一回答。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值