状态机设计与实现

模拟支付系统
支付流转图
代码实现:

/**
 * 状态基类
 */
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){
            // 异常处理
        }
    }
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,为您介绍一下状态机设计实现1101序列检测器的方法。 1101序列检测器的状态转移图如下所示: ``` 0/0 1/0 1/1 0/1 S0 ------> S1 ------> S2 ------> S3 ^ | | | | 1/0 1/1 0/1 \--------|---------|---------/ ``` 其中,S0、S1、S2、S3 分别为状态机的四个状态,0/0、1/0、1/1、0/1 分别表示输入为0时,状态转移后的下一状态和输出,输入为1时,状态转移后的下一状态和输出。 根据状态转移图,我们可以得到状态转移表: | 当前状态 | 输入 | 下一状态 | 输出 | | -------- | ---- | -------- | ---- | | S0 | 0 | S0 | 0 | | S0 | 1 | S1 | 0 | | S1 | 0 | S0 | 0 | | S1 | 1 | S2 | 0 | | S2 | 0 | S0 | 0 | | S2 | 1 | S3 | 1 | | S3 | 0 | S0 | 1 | | S3 | 1 | S1 | 0 | 然后,我们可以根据状态转移表设计状态机的 Verilog 代码: ```verilog module seq_detector(input clk, input reset, input data, output reg out); // 定义状态 typedef enum logic [1:0] { S0, S1, S2, S3 } state_t; // 定义状态寄存器和下一状态寄存器 reg [1:0] state, next_state; // 状态转移逻辑 always_comb begin case(state) S0: if (data) next_state = S1; else next_state = S0; S1: if (data) next_state = S2; else next_state = S0; S2: if (data) next_state = S3; else next_state = S0; S3: if (data) next_state = S1; else next_state = S0; endcase end // 输出逻辑 always_ff @(posedge clk, posedge reset) begin if (reset) begin state <= S0; out <= 0; end else begin state <= next_state; case(state) S0: out <= 0; S1: out <= 0; S2: out <= 0; S3: out <= 1; endcase end end endmodule ``` 这样,我们就完成了1101序列检测器的状态机设计实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值