「手写设计模式」状态模式

713 阅读2分钟

理解名词

先来理解状态机

有限状态机(Finite State Machine),缩写为 FSM,简称为状态机。状态机有 3 个组成部分:状态(State)、事件(Event)、动作(Action)。其中,事件也称为转移条件(Transition Condition)。事件触发状态的转移及动作的执行。动作不是必须的,也可能只转移状态,不执行任何动作。

作用

状态模式一般用来实现状态机,将事件触发的状态转移和动作执行解耦,拆分到不同的状态类中。

适用场景

存在有限状态的系统,且状态不多,状态转移较简单,但事件触发执行的动作包含的业务逻辑较为复杂。例如:

  • 工作流引擎
  • 电商下单,外卖下单

不适用场景:

  • 对于状态不多,状态转移简单,动作简单的状态机,使用分支逻辑法实现即可。

  • 对于状态很多,状态转移比较复杂的状态机,应使用查表法实现。

代码示例

以外卖下单为例,存在的状态有已下单,配送中,配送完成,订单已超时,订单已取消。

首先,定义状态类接口

public interface IOrderState {

    // 响应订单开始配送事件,默认实现为不支持,子类支持该事件时需要重写该方法
    default void onDeliver(OrderStateMachine machine) {
        throw new UnsupportedEventException();
    }
    
    // 响应订单开始配送完成事件,默认实现为不支持,子类支持该事件时需要重写该方法
    default void onDeliverCompleted(OrderStateMachine machine) {
        throw new UnsupportedEventException();
    }
    
    // 响应订单超时事件,默认实现为不支持,子类支持该事件时需要重写该方法
    default void onOrderTimeout(OrderStateMachine machine) {
        throw new UnsupportedEventException();
    }
    
    // 响应订单被取消事件,默认实现为不支持,子类支持该事件时需要重写该方法
    default void onOrderCancel(OrderStateMachine machine) {
        throw new UnsupportedEventException();
    }
}

状态机类实现

public class OrderStateMachine { 
    private IOrderState currentState; 
    
    public OrderStateMachine() { 
        this.currentState = InitOrderState.getInstance(); 
    } 
    
    public void onDeliver() {
        this.currentState.onDeliver(this); 
    }
    
    public void onDeliverCompleted() {
        this.currentState.onDeliverCompleted(this); 
    }
    
    public void onOrderTimeout() {
        this.currentState.onOrderTimeout(this); 
    }
    
    public void onOrderCancel() {
        this.currentState.onOrderCancel(this); 
    }

初始订单状态类实现

public class InitOrderState implements IOrderState {

    // 单例
    private static final InitOrderState instance = new InitOrderState();
    private InitOrderState() {} 
    public static InitOrderState getInstance() { return instance; }
    
    @Override
    public void onDeliver(OrderStateMachine machine) {
        // 开始配送...执行一些动作,例如推送骑手信息到App,开始计时等操作
        machine.setCurrentState(DeliverOrderState.getInstance());
    }
    
    @Override
    public void onOrderCancel(OrderStateMachine machine) {
        // 订单被取消...执行一些动作,例如退款
        machine.setCurrentState(CancelOrderState.getInstance());
    }
}

配送订单状态类实现

public class DeliverOrderState implements IOrderState {

    // 单例
    private static final DeliverOrderState instance = new DeliverOrderState();
    private DeliverOrderState() {} 
    public static DeliverOrderState getInstance() { return instance; }

    
    @Override
    public void onDeliverCompleted(OrderStateMachine machine) {
        // 配送已完成...执行一些动作,例如邀请评价,发放优惠券
        machine.setCurrentState(CompleteOrderState.getInstance());
    }
    
    @Override
    public void onOrderTimeout(OrderStateMachine machine) {
        // 订单配送超时...执行一些动作,例如推送App告知超时,发放超时赔偿
        machine.setCurrentState(TimeoutOrderState.getInstance());
    }
}

业界经典实现

  • Spring statemachine