使用枚举实现状态机来优雅你的状态变更逻辑

福利

现在关注微信公众号:码农小胖哥, 发送关键字【抽奖】进行抽奖,可有机会获取实体编程书籍。活动只剩下3天了抓紧参与!【本次抽奖截止到本周末】

前言

相信不少java开发者写过状态变更的业务,比如订单流程、请假流程等等。一般会搞一个状态标识来标识生命周期的某个阶段。很多人会写这种逻辑:

使用枚举实现状态机来优雅你的状态变更逻辑

如果流程几十个岂不是要if到爆炸。还有这“0”、“1”是几个意思?

优化的办法当然可以使用设计模式中的状态模式来搞,允许一个具有状态的对象根据其状态封装同一对象的不同行为。我们可以编程状态之间的转换,然后定义单独的状态:

使用枚举实现状态机来优雅你的状态变更逻辑

但是这种操作会增加过多的状态对象依赖。那么有没骚操作呢?当然有。我们先来了解了解状态机。

状态机

状态机全称有限状态机,因为一般的状态机的状态都是离散而且可枚举的,这就是有限的原因。状态机表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。通俗的描述状态机就是定义了一套状态変更的流程:状态机包含一个状态集合,定义当状态机处于某一个状态的时候它所能接收的事件以及可执行的行为,执行完成后,状态机所处的状态变化可以被感知。一般包含以下几个概念:

  • 状态 太废话了我,状态机没有状态还能叫状态机。
  • 事件 状态机的状态变更肯定是通过触发一个事件引起的。
  • 行为 触发了之后执行的业务逻辑。比如说订单未支付状态到支付状态的变更需要走的业务,写流水、修改账户余额等。
  • 变更 一个状态被一个事件触发执行了某些行为到达了另外一个状态的过程。

使用枚举实现状态机来优雅你的状态变更逻辑

上图就是个变更的过程示意。接下来该说另一个东西了。

## Java中的枚举

一个Java的枚举是一种定义的一类常量列表的特殊类型的类。是JDK 1.5中引入的新特性。 枚举在JDK中其实就是被设计成了单例模式,所以是不允许外部对其进行实例化的,枚举类型的实例化都是在其加载的时候JVM帮我们完成的。这是Java虚拟机规范明确规定的,保证了线程安全性。由于Java枚举隐式实现了枚举超类java.lang.Enum,因此无法实现另一个类,但是可以实现接口。可以声明抽象方法由具体的内部枚举来实现。我们定义一个颜色枚举来看看:

使用枚举实现状态机来优雅你的状态变更逻辑

我们可以通过 Colorful.RED.colorName() 直接拿到颜色的名称,非常方便而且语义化。

接下来我们将结合实际开发场景来实现一个简单枚举类型的状态机来处理业务。

实战操作

订单派送到收货这个场景,我们考虑如下单纯的场景:

使用枚举实现状态机来优雅你的状态变更逻辑

经历调度到派送最后到收货这个简单过程,我们可以定义如下状态枚举:

使用枚举实现状态机来优雅你的状态变更逻辑

因为调度是初始状态,所以其prevState方法指向自己,因为收货时终止状态所以其nextState指向自己。通过定义这两个指针来进行操作所需要的流程。当然实际生产要结合你自己的业务来做。

然后我们订单流程就可以这样搞(省略getter和setter):

使用枚举实现状态机来优雅你的状态变更逻辑

我们来简单测试一下:

使用枚举实现状态机来优雅你的状态变更逻辑

经过两次的流转,货物成功到达买家的手中,状态也正确的进行了变更,而且可维护性也得到了保证,只需要变更枚举流程。好了今天就到这里,希望大家多多关注。

关注公众号:码农小胖哥 获取更多资讯

原文 

https://segmentfault.com/a/1190000020216365

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 使用枚举实现状态机来优雅你的状态变更逻辑

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址