说明:本文只是在个人实战中的示例,主要了解思想,代码可根据自己的具体情况进行调整,不是完整的demo代码。
背景说明
订单存在下单、支付、运输、完成等此类的状态流转,每一个状态下做不同的业务处理,状态存在变更的情况。
期望能够通过配置来实现状态变更时不影响历史代码并且不做变更,仅针对新状态进行业务开发即可。
方案说明
个人的解决方案是这样的,仅供参考:
1、状态具体的流转步骤通过配置文件完成
2、每个状态要做的业务逻辑面向接口开发
3、使用指令模式来进行控制
4、具体指令配置在配置文件中
5、指令就是状态code
6、通过策略模式进行封装仅对外暴露一个接口
7、通过桥连接模式将具体的状态机流转进行处理
代码
第一步、配置文件
- 梳理自己所需要的状态,每一个状态code就是一个指令
- 每一个指令对应了一个具体的业务接口实现类
- 不同的产品可能有不同的状态流转,需要支持多产品集合
配置文件示例如下,代码仅供参考,可根据自己的业务进行不同的字段增减:
配置内容我写在了bootstrap.yml文件中了,根据自己的业务进行调整
#自定义状态机
statemachine:
products: #产品集合
- name: gome_cuohe #产品标识
open: true #产品启用开关
states: #产品状态集合
#角色分别为:系统(SYSTEM)、雇主(A)、服务商(B)
- service: OrderStateMachineXXXServiceImpl #状态机需要执行的service
roles: A,B#支持的角色
instructions: xxx #指令
des: #描述
- service: OrderStateMachineSelectYYYServiceImpl #状态机需要执行的service
roles: B#支持的角色
instructions: yyy #指令
des: #描述
创建对应配置内容的映射java类
@Data
@Configuration
@ConfigurationProperties(prefix = "statemachine")
public class StateMachineConfig {
List<StateMachineProduct> products = Lists.newArrayList();
}
@Data
public class StateMachineProduct {
String name;
Boolean open;
List<StateMachineProductState> states = Lists.newArrayList();
}
@Data
public class StateMachineProductState {
String service;
String roles;
String instructions;
String des;
}
第二步、定义状态机接口
状态机具体执行的service接口定义
<