自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊Cola-StateMachine輕量級狀態(tài)機(jī)的實現(xiàn)

開發(fā)
對于Saga模式的實現(xiàn),之前的博文中已經(jīng)闡述了基于狀態(tài)機(jī)模式實現(xiàn)Saga,是比較常見且合適的做法,因此了解了下Java中的狀態(tài)機(jī)實現(xiàn)方案,以后有相關(guān)的業(yè)務(wù)場景也可以直接上手使用狀態(tài)機(jī)。

背景

在分析Seata的saga模式實現(xiàn)時,實在是被其復(fù)雜的 json 狀態(tài)語言定義文件勸退,我是有點(diǎn)沒想明白為啥要用這么來實現(xiàn)狀態(tài)機(jī);盲猜可能是基于可視化的狀態(tài)機(jī)設(shè)計器來定制化流程,更方便快捷且上手快吧,畢竟可以通過UI直接操作,設(shè)計狀態(tài)流轉(zhuǎn)圖,但我暫時不太能get到。對于Saga模式的實現(xiàn),之前的博文中已經(jīng)闡述了基于狀態(tài)機(jī)模式實現(xiàn)Saga,是比較常見且合適的做法,因此了解了下Java中的狀態(tài)機(jī)實現(xiàn)方案,以后有相關(guān)的業(yè)務(wù)場景也可以直接上手使用狀態(tài)機(jī)。

Cola-StateMachine

Cola-StateMachine組件是一種輕量級的、無狀態(tài)的、基于注解的狀態(tài)機(jī)實現(xiàn),可以方便地管理訂單等業(yè)務(wù)對象的狀態(tài)轉(zhuǎn)換。COLA框架的狀態(tài)機(jī)使用了連貫接口(Fluent Interfaces)來定義狀態(tài)和事件,以及對應(yīng)的動作和檢查。COLA框架的狀態(tài)機(jī)是COLA 4.0應(yīng)用架構(gòu)的一部分,旨在控制復(fù)雜度,提高開發(fā)效率。開發(fā)背景可見實現(xiàn)一個狀態(tài)機(jī)引擎,教你看清DSL的本質(zhì)。

基礎(chǔ)模型

在Cola-StateMachine組件中有如下的抽象概念模型:

1.State:狀態(tài)
2.Event:事件,狀態(tài)由事件觸發(fā),引起變化
3.Transition:流轉(zhuǎn),表示從一個狀態(tài)到另一個狀態(tài)
4.External Transition:外部流轉(zhuǎn),兩個不同狀態(tài)之間的流轉(zhuǎn)
5.Internal Transition:內(nèi)部流轉(zhuǎn),同一個狀態(tài)之間的流轉(zhuǎn)
6.Condition:條件,表示是否允許到達(dá)某個狀態(tài)
7.Action:動作,到達(dá)某個狀態(tài)之后,可以做什么
8.StateMachine:狀態(tài)機(jī)

Cola-StateMachine鏈路圖

業(yè)務(wù)應(yīng)用示例

基于訂單業(yè)務(wù)的場景,做一個簡單的demo。

關(guān)閉訂單的簡單流程圖

關(guān)閉訂單簡單的狀態(tài)流轉(zhuǎn)圖

添加依賴

<dependency>
    <groupId>com.alibaba.cola</groupId>
    <artifactId>cola-component-statemachine</artifactId>
    <version>4.3.1</version>
</dependency>

定義一個訂單的實體類、訂單狀態(tài)的枚舉值、訂單事件的枚舉值

@Data
@Builder
public class Order {

    public OrderStatusEnum orderStatusEnum;
    public Integer orderId;
    public String orderName;

}

public enum OrderStatusEnum {
    INIT("0", "待付款"),
    WAITING_FOR_DELIVERY("1", "待發(fā)貨"),
    HAVE_BEEN_DELIVERY("2", "已發(fā)貨"),
    CLOSE("3", "已取消");


    private final String code;
    private final String info;

    OrderStatusEnum(String code, String info)
    {
        this.code = code;
        this.info = info;
    }

    public String getCode()
    {
        return code;
    }

    public String getInfo()
    {
        return info;
    }
}

public enum OrderEvent {
    /**
     * 用戶關(guān)閉
     */
    USER_CLOSE("0", "用戶取消"),
    /**
     * 管理員關(guān)閉
     */
    ADMIN_CLOSE("1", "后臺取消"),
    /**
     * 超時關(guān)閉
     */
    OVERTIME_CLOSE("2", "超時取消"),
    /**
     * 檢查錯誤關(guān)閉
     */
    CHECK_ERROR_CLOSE("3", "上級審核取消"),

    /**
     * 用戶付費(fèi)
     */
    USER_PAY("4", "用戶支付");


    /**
     * 密碼
     */
    private final String code;
    /**
     * 信息
     */
    private final String info;

    /**
     * 訂單事件
     *
     * @param code 密碼
     * @param info 信息
     */
    OrderEvent(String code, String info) {
        this.code = code;
        this.info = info;
    }

    /**
     * 獲取代碼
     *
     * @return {@link String}
     */
    public String getCode() {
        return code;
    }

    /**
     * 獲取信息
     *
     * @return {@link String}
     */
    public String getInfo() {
        return info;
    }
}

在容器啟動的時候注冊一個訂單狀態(tài)變更的工廠

@Component
public class StateMachineBuilderConfig {
    @Autowired
    UserCloseAction userCloseAction;

    @Bean("orderOperaMachine")
    public StateMachine orderOperaMachine() {
        String ORDER_OPERA = "order_opera";
        StateMachineBuilder<OrderStatusEnum, OrderEvent, Order> builder = StateMachineBuilderFactory.create();
        //訂單從初始化狀態(tài)-待發(fā)貨-狀態(tài)-轉(zhuǎn)到-關(guān)閉訂單狀態(tài)--用戶關(guān)閉
        builder.externalTransitions()
                .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.WAITING_FOR_DELIVERY)
                .to(OrderStatusEnum.CLOSE)
                .on(OrderEvent.USER_CLOSE)
                .when(checkCondition())
                .perform(userCloseAction);
        //訂單從-初始化狀態(tài)-已發(fā)貨-待發(fā)貨--轉(zhuǎn)到-關(guān)閉訂單狀態(tài)--后臺操作人員關(guān)閉
        builder.externalTransitions()
                .fromAmong(OrderStatusEnum.INIT, OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderStatusEnum.WAITING_FOR_DELIVERY)
                .to(OrderStatusEnum.CLOSE)
                .on(OrderEvent.ADMIN_CLOSE)
                .when(checkCondition())
                .perform(doAction());
        //訂單從等待發(fā)貨狀態(tài)-轉(zhuǎn)為-訂單關(guān)閉狀態(tài)-超時關(guān)閉
        builder.externalTransition()
                .from(OrderStatusEnum.WAITING_FOR_DELIVERY)
                .to(OrderStatusEnum.CLOSE)
                .on(OrderEvent.OVERTIME_CLOSE)
                .when(checkCondition())
                .perform(doAction());
        //訂單從待發(fā)貨狀態(tài)--轉(zhuǎn)為-訂單關(guān)閉狀態(tài)-上級審批不通過關(guān)閉
        builder.externalTransition()
                .from(OrderStatusEnum.WAITING_FOR_DELIVERY)
                .to(OrderStatusEnum.CLOSE)
                .on(OrderEvent.CHECK_ERROR_CLOSE)
                .when(checkCondition())
                .perform(doAction());
        //訂單從初始化狀態(tài)--轉(zhuǎn)為待發(fā)貨狀態(tài)--用戶支付完畢動
        builder.externalTransition()
                .from(OrderStatusEnum.INIT)
                .to(OrderStatusEnum.WAITING_FOR_DELIVERY)
                .on(OrderEvent.USER_PAY)
                .when(checkCondition())
                .perform(doAction());

        StateMachine orderOperaMachine = builder.build(ORDER_OPERA);

        //打印uml圖
        String plantUML = orderOperaMachine.generatePlantUML();
        System.out.println(plantUML);
        return orderOperaMachine;
    }

    private Condition<Order> checkCondition() {
        return (ctx) -> {
            return true;
        };
    }

    private Action<OrderStatusEnum, OrderEvent, Order> doAction() {
        return (from, to, event, ctx) -> {
            System.out.println(ctx.getOrderName() + " 正在操作 " + ctx.getOrderId() + " from:" + from + " to:" + to + " on:" + event);
        };
    }

}

在定義一個特殊的,只是舉個例子,可以通過集成的方式集成實現(xiàn)一個用戶關(guān)單的具體操作

@Component
public class UserCloseAction implements Action<OrderStatusEnum, OrderEvent, Order> {

    @Override
    public void execute(OrderStatusEnum from, OrderStatusEnum to, OrderEvent event, Order context) {
        System.out.println("用戶關(guān)閉流程開始走了");
        System.out.println("從這個狀態(tài)-【" + from.getInfo() + "】-轉(zhuǎn)為+【" + to.getInfo() + "】 的狀態(tài)");
        System.out.println("上下文信息:" + context.toString());
        System.out.println("中間執(zhí)行的一些操作.......");
        System.out.println("用戶關(guān)閉流程完畢了");
    }
}

定義一個 controller 的操作接口

@RestController
public class OrderOperaController {

    @Autowired
    @Qualifier("orderOperaMachine")
    StateMachine<OrderStatusEnum, OrderEvent, Order> orderOperaMachine;

    /**
     * 場景1-用戶關(guān)閉訂單
     *
     * @return {@link Boolean}
     */
    @RequestMapping("userclose")
    public Boolean userCloseOrder() {
        //把訂單狀態(tài)改為關(guān)閉
        String machineId = orderOperaMachine.getMachineId();
        System.out.println(machineId);
        Order order = Order.builder().orderId(1).orderName("用戶").orderStatusEnum(OrderStatusEnum.INIT).build();
        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.INIT,OrderEvent.USER_CLOSE, order);
        System.out.println(orderStatusEnum.toString());
        return true;
    }

    /**
     * 場景2-管理員關(guān)閉訂單
     *
     * @return {@link Boolean}
     */
    @RequestMapping("adminClose")
    public Boolean adminCloseOrder() {
        //把訂單狀態(tài)改為關(guān)閉
        Order order = Order.builder().orderId(1).orderName("后臺操作人員").orderStatusEnum(OrderStatusEnum.HAVE_BEEN_DELIVERY).build();
        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.HAVE_BEEN_DELIVERY, OrderEvent.ADMIN_CLOSE, order);
        System.out.println(orderStatusEnum.toString());

        return true;
    }

    /**
     * 場景3-超時關(guān)閉訂單
     *
     * @return {@link Boolean}
     */
    @RequestMapping("overTimeclose")
    public Boolean overTimeCloseOrder() {
        //把訂單狀態(tài)改為關(guān)閉
        Order order = Order.builder().orderId(1).orderName("超時了關(guān)閉訂單")
                .orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build();
        //OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.CLOSE, OrderEvent.OVERTIME_CLOSE, order);
        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.OVERTIME_CLOSE, order);
        System.out.println(orderStatusEnum.toString());
        return true;
    }

    /**
     * 場景4-檢查錯誤關(guān)閉訂單
     *
     * @return {@link Boolean}
     */
    @RequestMapping("checkErrorClose")
    public Boolean checkErrorCloseOrder() {
        //把訂單狀態(tài)改為關(guān)閉
        Order order = Order.builder().orderId(1).orderName("上級檢查錯誤").orderStatusEnum(OrderStatusEnum.WAITING_FOR_DELIVERY).build();
        OrderStatusEnum orderStatusEnum = orderOperaMachine.fireEvent(OrderStatusEnum.WAITING_FOR_DELIVERY, OrderEvent.CHECK_ERROR_CLOSE, order);
        System.out.println(orderStatusEnum.toString());
        return true;
    }
}

啟動程序

安裝UML

隨便新建一個uml文件,然后將啟動程序的控制臺輸出內(nèi)容復(fù)制到uml中

最后運(yùn)行下

責(zé)任編輯:張燕妮 來源: 互聯(lián)網(wǎng)架構(gòu)小馬哥
相關(guān)推薦

2022-03-06 19:57:50

狀態(tài)機(jī)easyfsm項目

2024-10-10 17:46:06

2011-06-24 16:09:24

Qt 動畫 狀態(tài)機(jī)

2024-08-26 14:32:43

2023-03-06 07:35:30

狀態(tài)機(jī)工具訂單狀態(tài)

2020-12-02 13:33:58

函數(shù)指針編程語言

2021-07-08 09:15:20

單片機(jī)編程狀態(tài)機(jī)編程語言

2010-06-18 12:38:38

UML狀態(tài)機(jī)視圖

2013-09-03 09:57:43

JavaScript有限狀態(tài)機(jī)

2010-06-18 13:25:44

UML狀態(tài)機(jī)視圖

2020-03-27 10:50:29

DSL 狀態(tài)機(jī)工具

2011-06-29 18:36:59

Qt 動畫 狀態(tài)機(jī)

2023-12-13 08:22:45

SQLite關(guān)系型數(shù)據(jù)庫

2020-10-15 10:38:35

C語言狀態(tài)模型

2021-04-29 09:31:05

前端開發(fā)技術(shù)

2010-07-08 13:03:31

UML狀態(tài)機(jī)圖

2010-07-12 15:00:56

UML狀態(tài)機(jī)視圖

2021-08-19 09:00:00

微服務(wù)開發(fā)架構(gòu)

2021-12-28 08:24:18

函數(shù)指針有限狀態(tài)機(jī)編程

2011-08-22 10:52:30

iptables狀態(tài)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號