模拟支付系统
代码实现:
/**
* 状态基类
*/
public interface BaseStatus {
}
/**
* 事件基类
*/
public interface BaseEvent {
}
/**
* 状态事件对,指定状态只能接受指定的事件
*/
public class StatusEventPair<S extends BaseStatus, E extends BaseEvent> {
/**
* 指定的状态
*/
private final S status;
/**
* 可接受的事件
*/
private final E event;
public StatusEventPair(S status, E event){
this.status = status;
this.event = event;
}
}
import java.util.HashMap;
import java.util.Map;
public class StateMachine<S extends BaseStatus, E extends BaseEvent> {
private final Map<StatusEventPair<S, E>, S> statusEventMap = new HashMap<>();
/**
* 只接受指定的当前的状态下,指定的事件触发,可以到达的指定目标状态
*/
public void accept(S sourceStatus, E event, S targetStatus){
statusEventMap.put(new StatusEventPair<>(sourceStatus, event), targetStatus);
}
/**
* 通过源状态和事件,获取目标状态
*/
public S getTargetStatus(S sourceStatus, E event){
return statusEventMap.get(new StatusEventPair<>(sourceStatus, event));
}
}
/**
* 支付事件
*/
public enum PaymentEvent implements BaseEvent{
PAY_CREATE("PAY_CREATE", "支付创建"),
PAY_PROCESS("PAY_PROCESS", "支付中"),
PAY_SUCCESS("PAY_SUCCESS", "支付成功"),
PAY_FAIL("PAY_FAIL", "支付失败"),
;
private String event;
private String desc;
PaymentEvent(String event, String desc){
}
}
/**
* 支付状态机
*/
public enum PaymentStatus implements BaseStatus{
INIT("INIT", "初始化"),
PAYING("PAYING", "支付中"),
PAID("PAID", "支付成功"),
FAILED("FAILED", "支付失败"),
;
private String status;
private String desc;
PaymentStatus(String status, String desc) {
}
// 支付状态机内容
private static final StateMachine<PaymentStatus, PaymentEvent> STATE_MACHINE = new StateMachine<>();
static {
// 初始状态
STATE_MACHINE.accept(null, PaymentEvent.PAY_CREATE, INIT);
// 支付中
STATE_MACHINE.accept(INIT, PaymentEvent.PAY_PROCESS, PAYING);
// 支付成功
STATE_MACHINE.accept(PAYING, PaymentEvent.PAY_SUCCESS, PAID);
// 支付失败
STATE_MACHINE.accept(PAYING, PaymentEvent.PAY_FAIL, FAILED);
}
public static PaymentStatus getTargetStatus(PaymentStatus status, PaymentEvent event){
return STATE_MACHINE.getTargetStatus(status, event);
}
}
public class PaymentModel {
//上次状态
private PaymentStatus lastStatus;
// 当前状态
private PaymentStatus currentStatus;
/**
* 根据事件推进状态
*/
public void transferStatusByEvent(PaymentEvent event){
// 根据当前状态和事件,去获取目标状态
PaymentStatus targetStatus = PaymentStatus.getTargetStatus(currentStatus, event);
// 如果目标状态不为空,说明可以推进
if (targetStatus != null){
lastStatus = currentStatus;
currentStatus = targetStatus;
} else {
// 目标为空,说明非法推进,进入异常处理
throw new RuntimeException("状态转换失败");
}
}
}
测试:
/**
* 支付结果通知
*/
public void notify(String event){
// 获取paymentModel
PaymentModel paymentModel = new PaymentModel();
try{
// 状态推进
paymentModel.transferStatusByEvent(PaymentEvent.valueOf(event));
// 其他业务处理
} catch (Exception e){
// 异常处理
}
}