一、状态模式概述
状态模式一般用来实现状态机,而状态机常用在游戏、工作流引擎等系统开发中。不过,状态机的实现方式有多种,除了状态模式,比较常用的还有分支逻辑法和查表法。
有限状态机,英文翻译是 Finite State Machine,缩写为 FSM,简称为状态机。状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。
二、状态模式的三种实现方式
以支付收获为例。
三种状态State:未支付、未收货、完成。
两种事件Event:支付、收货。
状态的流转即动作:支付后状态为未收货,收获后状态为完成。
/**
* 支付状态枚举
*/
@Getter
public enum PayStateEnum {
/**
* 待支付
*/
UNPAY(0),
/**
* 待收货
*/
UNRECEIVE(1),
/**
* 完成
*/
FINAL(2),
/**
* 错误
*/
ERROR(3);
/**
* 值
*/
private int value;
PayStateEnum(int value) {
this.value = value;
}
}
/**
* 支付事件枚举
*/
@Getter
public enum PayEventEnum {
/**
* 支付
*/
PAY(0),
/**
* 收货
*/
RECEIVE(1);
/**
* 值
*/
private int value;
PayEventEnum(int value) {
this.value = value;
}
}
2.1 逻辑分支
使用if-else或者switch-case
进行处理的方式
/**
* 支付状态机:逻辑分支
*/
@Slf4j
public class PayStateMachine {
/**
* 当前状态
*/
private PayStateEnum payStateEnum;
public PayStateMachine() {
payStateEnum = PayStateEnum.UNPAY;
}
public void executeEvent(PayEventEnum payEventEnum) {
switch (payEventEnum) {
//支付行为发生:未支付->待收货
case PAY:
if (this.payStateEnum != PayStateEnum.UNPAY) {
log.info("商铺不是【未支付】状态,请核验!");
this.payStateEnum = PayStateEnum.ERROR;
break;
}
this.payStateEnum = PayStateEnum.UNRECEIVE;
break;
//收货行为发生:待收货->完成
case