什么是状态
在现实世界中事务是有不同状态的。比如一扇门,就会存在open和close状态。而我们一般所指的状态机是指有限状态机,也就是状态的个数是有限的。
状态机的用途
状态机的用途只是为了让程序员更好的理解状态的流转过程,但是不会在业务中规定死状态的变化。
状态机的抽象
可以抽象为:
初始状态、最终状态、触发状态改变的事件、和状态改变时需要的动作(也就是业务流程)
以在电商平台订单付款为例。
初始状态:待付款
最终状态:待发货
事件:用户付款
动作:表示事件成功后需要的业务流程,例如创建物流、更新db状态等等。
下面实现使用java 实现状态机:
用事件规范状态的流转。
import java.util.function.Function;
/**
* 事件枚举 用户规范状态转换流程
*/
public enum EventEnum {
/**
* 支付
*/
PAY(1,"支付", StatusEnum.WAIT_PAY, StatusEnum.WAIT_DELIVERY,null),
/**
* 发货
*/
SHIPMENTS(2,"发货", StatusEnum.WAIT_DELIVERY, StatusEnum.IN_TRANSIT,null);
private int key;
private String name;
private StatusEnum startState;
private StatusEnum endState;
private Function action;
EventEnum(int key, String name, StatusEnum startState, StatusEnum endState, Function actionEnum) {
this.key = key;
this.name = name;
this.startState = startState;
this.endState = endState;
this.action = actionEnum;
}
public int getKey() {
return key;
}
public String getName() {
return name;
}
public StatusEnum getStartState() {
return startState;
}
public StatusEnum getEndState() {
return endState;
}
public Function getAction() {
return action;
}
public void setKey(int key) {
this.key = key;
}
public void setName(String name) {
this.name = name;
}
public void setStartState(StatusEnum startState) {
this.startState = startState;
}
public void setEndState(StatusEnum endState) {
this.endState = endState;
}
public void setAction(Function actionEnum) {
this.action = actionEnum;
}
}
状态枚举
/**
* 状态枚举
*/
public enum StatusEnum {
WAIT_PAY(1,"待支付"),
WAIT_DELIVERY(2,"待发货"),
IN_TRANSIT(3,"运输中")
;
private int key;
private String name;
StatusEnum(int key, String name) {
this.key = key;
this.name = name;
}
}
测试类
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class Manager<P,R> {
public R eventExec(EventEnum eventEnum, P parameter){
if (eventEnum.getAction()==null) {
log.info("无业务操作");
return null;
}
return (R)eventEnum.getAction().apply(parameter);
}
@Data
@NoArgsConstructor
static class Order {
Integer id;
StatusEnum status;
String desc;
public Order(Integer id, StatusEnum status) {
this.id = id;
this.status = status;
}
}
static List<Order> orderList = Lists.newArrayList(
new Order(1,StatusEnum.WAIT_PAY),
new Order(2,StatusEnum.WAIT_PAY),
new Order(3,StatusEnum.WAIT_PAY)
);
public static void main(String[] args) {
Manager<Order, Order> manager = new Manager<>();
EventEnum.PAY.setAction(p -> {
Order order = (Order)p;
log.info("状态机执行前:{}",order);
order.setStatus(StatusEnum.WAIT_DELIVERY);
order.setDesc("改变状态了");
return order;
});
Order order = manager.eventExec(EventEnum.PAY, orderList.get(0));
log.info("{}",order);
}
}