日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Java生鲜电商平台-订单模块状态机架构设计

發(fā)布時(shí)間:2023/12/13 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 Java生鲜电商平台-订单模块状态机架构设计 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java生鮮電商平臺-訂單模塊狀態(tài)機(jī)架構(gòu)設(shè)計(jì)

說明:在Java生鮮電商平臺中訂單的狀態(tài)流轉(zhuǎn)業(yè)務(wù)

我們知道 一個(gè)訂單會(huì)有很多種狀態(tài):臨時(shí)單、已下單、待支付、待收貨、待評價(jià)、已完成,退貨中等等。每一種狀態(tài)都和其扭轉(zhuǎn)前的狀態(tài)、在扭轉(zhuǎn)前狀態(tài)所執(zhí)行的操作有關(guān)。

一 實(shí)例說明

舉例一個(gè)過程:用戶將商品加入購物車,在后臺生成了一個(gè)所謂的“臨時(shí)單”,這個(gè)訂單實(shí)際上還沒有正式生成,因?yàn)橛脩羧匀粵]有點(diǎn)擊下單。只有當(dāng)用戶下單后,這個(gè)“臨時(shí)單”才可以轉(zhuǎn)化為一個(gè)“待支付的訂單”。那么這個(gè)過程中:只有將一個(gè)處于“臨時(shí)單”狀態(tài)的訂單執(zhí)行下單操作,才能得到一個(gè)狀態(tài)為“待支付”的訂單。 即--一個(gè)前置狀態(tài)+一個(gè)恰當(dāng)?shù)牟僮鳎拍芘まD(zhuǎn)訂單的狀態(tài)。在這個(gè)過程中,如果是硬編碼,那么我們需要一系列的 if...else 語句來檢查訂單的當(dāng)前狀態(tài)、可執(zhí)行操作以及這兩個(gè)的組合得到的下一個(gè)應(yīng)該被流轉(zhuǎn)的狀態(tài)值。如果訂單的狀態(tài)流轉(zhuǎn)很復(fù)雜的話,寫出來的邏輯就會(huì)很復(fù)雜,并且可讀性很低。后期的維護(hù)就是一個(gè)坑。

二 狀態(tài)設(shè)計(jì)模式與訂單狀態(tài)流轉(zhuǎn)

處理這個(gè)問題,我們可以使用 狀態(tài)機(jī)設(shè)計(jì)模式 來處理。對應(yīng)到實(shí)踐,就是狀態(tài)機(jī)。

關(guān)于狀態(tài)機(jī)設(shè)計(jì)模式的具體內(nèi)容,可以自行百度。這里用簡單的一句話來概括的話:對象的內(nèi)部狀態(tài)隨外部執(zhí)行條件的變化而變化。再映射到訂單狀態(tài)的流轉(zhuǎn)上:訂單的狀態(tài),隨訂單當(dāng)前狀態(tài)和目前執(zhí)行操作的組合而變化。

三 編碼前的抽象與設(shè)計(jì)


圖示模擬一個(gè)訂單狀態(tài)的流轉(zhuǎn)流程。從一個(gè)臨時(shí)訂單開始,每當(dāng)訂單處于某一個(gè)已知的狀態(tài)的時(shí)候,要想讓這個(gè)訂單改變狀態(tài),就需要我們?nèi)?zhí)行對應(yīng)的操作。

從狀態(tài)機(jī)角度來說,我們先將各種信息進(jìn)行抽象和處理

3.1 代碼抽象

編寫對應(yīng)訂單狀態(tài)枚舉類

public enum OrderStatusEnum {

    CREATE_EVENT(1, "創(chuàng)建訂單"),
    FORMAL_EVENT(2, "正式訂單"),
    NEED_PAY(3, "待支付"),
    PAY_DONE(4, "已支付"),
    ORDER_FINISHED(5, "訂單已完成"),

    ORDER_CANCEL(6, "訂單已取消");

    OrderStatusEnum(int status, String desc) {
        this.status = status;
        this.desc = desc;
    }

    public int status;

    public String desc;
}

枚舉類中先準(zhǔn)備好需要用的狀態(tài)信息。

先用一張圖來描述整個(gè)工作機(jī)制:


然后是需要的核心代碼部分:一個(gè)管理訂單狀態(tài)的中轉(zhuǎn)站manager類,一組用于扭轉(zhuǎn)訂單狀態(tài)的operator類,一組扭轉(zhuǎn)完訂單狀態(tài)后執(zhí)行后續(xù)邏輯操作的processor類。

manager類需要根據(jù)對應(yīng)傳入的當(dāng)前訂單狀態(tài)、要對該訂單執(zhí)行操作來得到這個(gè)訂單的結(jié)果狀態(tài)(依靠對應(yīng)的opertor類),然后執(zhí)行一系列需要的業(yè)務(wù)邏輯操作(編寫對應(yīng)的processor類)。這樣的好處就是將訂單狀態(tài)流轉(zhuǎn)和對應(yīng)的業(yè)務(wù)處理解耦。并且也不會(huì)再有一堆繁雜的 if...else 操作。每當(dāng)需要新的訂單狀態(tài)流轉(zhuǎn)操作的時(shí)候,可以去編寫對應(yīng)的一套o(hù)perator和processor組件來完成,和已有業(yè)務(wù)的分離度很高。

接下來貼代碼舉例


/**
 * 訂單狀態(tài)流轉(zhuǎn)管理器--狀態(tài)機(jī)核心組件
 * @author Java生鮮電商平臺
 *
 **/
@Component
public class OrderStateManager {

    Map<Integer, AbstractOrderOperator> orderOperatorMaps = new HashMap<Integer, AbstractOrderOperator>();

    Map<Integer, AbstractOrderProcessor> orderProcessorMaps = new HashMap<Integer, AbstractOrderProcessor>();

    public OrderStateManager() { }

    /**
     * 狀態(tài)流轉(zhuǎn)方法
     * @param orderId 訂單id
     * @param event 流轉(zhuǎn)的訂單操作事件
     * @param status 當(dāng)前訂單狀態(tài)
     * @return 扭轉(zhuǎn)后的訂單狀態(tài)
     */
    public int handleEvent(final String orderId, OrderStatusEnum event, final int status) {
        if (this.isFinalStatus(status)) {
            throw new IllegalArgumentException("handle event can't process final state order.");
        }
        // 獲取對應(yīng)處理器,根據(jù)入?yún)顟B(tài)和時(shí)間獲取訂單流轉(zhuǎn)的結(jié)果狀態(tài)
        AbstractOrderOperator abstractOrderOperator = this.getStateOperator(event);
        int resState = abstractOrderOperator.handleEvent(status, event);
        // 得到結(jié)果狀態(tài),在對應(yīng)的processor中處理訂單數(shù)據(jù)及其相關(guān)信息
        AbstractOrderProcessor orderProcessor = this.getOrderProcessor(event);
        if (!orderProcessor.process(orderId, resState)) {
            throw new IllegalStateException(String.format("訂單狀態(tài)流轉(zhuǎn)失敗,訂單id:%s", orderId));
        }
        return resState;
    }

    /**
     * 根據(jù)入?yún)顟B(tài)枚舉實(shí)例獲取對應(yīng)的狀態(tài)處理器
     * @param event event
     * @return
     */
    private AbstractOrderOperator getStateOperator(OrderStatusEnum event) {
        AbstractOrderOperator operator = null;
        for (Map.Entry<Integer, AbstractOrderOperator> entry: orderOperatorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                operator = entry.getValue();
            }
        }
        if (null == operator) {
            throw new IllegalArgumentException(String.format("can't find proper operator. The parameter state :%s", event.toString()));
        }
        return operator;
    }

    /**
     * 根據(jù)入?yún)顟B(tài)枚舉實(shí)例獲取對應(yīng)的狀態(tài)后處理器
     * @param event event
     * @return
     */
    private AbstractOrderProcessor getOrderProcessor(OrderStatusEnum event) {
        AbstractOrderProcessor processor = null;
        for (Map.Entry<Integer, AbstractOrderProcessor> entry : orderProcessorMaps.entrySet()) {
            if (event.status == entry.getKey()) {
                processor = entry.getValue();
            }
        }
        if (null == processor) {
            throw new IllegalArgumentException(String.format("can't find proper processor. The parameter state :%s", event.toString()));
        }
        return processor;
    }

    /**
     * 判斷是不是已完成訂單
     * @param status 訂單狀態(tài)碼
     * @return
     */
    private boolean isFinalStatus(int status) {
        return OrderStatusEnum.ORDER_FINISHED.status == status;
    }

}

核心的代碼就是類中的 handleEvent 方法。

對應(yīng)的獲取到的組件處理類示例:

/**
 * @author Java生鮮電商平臺-訂單模塊狀態(tài)機(jī)架構(gòu)設(shè)計(jì)
 **/
@Data
public abstract class AbstractOrderOperator {

    int status;

    public abstract int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum);
}
===================================
/**
 * 創(chuàng)建訂單操作狀態(tài)流轉(zhuǎn)
 * Java生鮮電商平臺-訂單模塊狀態(tài)機(jī)架構(gòu)設(shè)計(jì)
 **/
@Component
@OrderOperator
public class CreateOrderOperator extends AbstractOrderOperator {

    public CreateOrderOperator() {
        super.setStatus(1);
    }

    @Override
    public int handleEvent(int orderStatus, OrderStatusEnum orderStatusEnum) {
        if (orderStatus != OrderStatusEnum.CREATE_EVENT.status && orderStatus != OrderStatusEnum.ORDER_CANCEL.status) {
            throw new IllegalArgumentException(String.format("create operation can't handle the status: %s", orderStatus));
        }
        System.out.println("進(jìn)入創(chuàng)建訂單狀態(tài)扭轉(zhuǎn)處理器...");
        switch (orderStatusEnum) {
            case CREATE_EVENT:
                return OrderStatusEnum.FORMAL_EVENT.status;
            case ORDER_CANCEL:
                return OrderStatusEnum.ORDER_CANCEL.status;
            default:
                return getStatus();
        }
    }
}

后處理器

/**
 * 訂單處理器
 **/
@Data
public abstract class AbstractOrderProcessor {

    int status;

    public abstract boolean process(String orderId, Object... params);
}
@Component @OrderProcessor public class CreateOrderProcessor extends AbstractOrderProcessor{ public CreateOrderProcessor() { super.setStatus(1); } @Override public boolean process(String orderId, Object... params) { // TODO 創(chuàng)建/取消訂單對應(yīng)的數(shù)據(jù)庫修改,mq發(fā)送等操作,可以在此處process方法中完成 System.out.println("進(jìn)入創(chuàng)建訂單后處理器..."); return true; } }

這些組件類都是依賴于spring的組件掃描注入。如果要定制化地處理自己的組件類。可以用一些其他的技巧來處理。比如此處使用到了自定義注解,通過自定義注解+自定義狀態(tài)機(jī)初始化類來完成對應(yīng)組件類的篩選與初始化。將這個(gè)初始化類加載完畢,狀態(tài)機(jī)就可以正常使用了。

/**
 * 狀態(tài)機(jī)前置激活類,在spring中掃描配置此類 <br/>
 * 使用自定義注解標(biāo)記對應(yīng)的狀態(tài)處理器和后置處理器并在初始化操作中完成對應(yīng)處理器的初始化。
 **/
@Component
public class Initialization implements BeanPostProcessor {

    @Resource
    OrderStateManager manager;

    @Nullable
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof AbstractOrderOperator && bean.getClass().isAnnotationPresent(OrderOperator.class) ) {
            AbstractOrderOperator orderState = (AbstractOrderOperator) bean;
            manager.orderOperatorMaps.put(orderState.getStatus(), orderState);
        }
        if (bean instanceof AbstractOrderProcessor && bean.getClass().isAnnotationPresent(OrderProcessor.class) ) {
            AbstractOrderProcessor orderProcessor = (AbstractOrderProcessor) bean;
            manager.orderProcessorMaps.put(orderProcessor.getStatus(), orderProcessor);
        }
        return bean;
    }
}

這里有一個(gè)問題就是在正式開發(fā)環(huán)境中,依賴于項(xiàng)目的spring環(huán)境,需要在狀態(tài)機(jī)正式運(yùn)行前將對應(yīng)的狀態(tài)扭轉(zhuǎn)組件類(operator和processor)注入到環(huán)境中。

聯(lián)系QQ:137071249

QQ群:793305035

總結(jié)

以上是生活随笔為你收集整理的Java生鲜电商平台-订单模块状态机架构设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 内谢少妇xxxxx8老少交视频 | 综合色区| 亚洲逼图| 国产成人综合在线观看 | 嫩草视频在线 | 99青青草 | av中文天堂在线 | 亚洲午夜天堂 | 二级毛片视频 | 美女精品一区 | 免费看黄色的视频 | 日本一区二区三区在线播放 | 欧美xxxxxhd| 欧洲精品一区二区 | 希岛婚前侵犯中文字幕在线 | 亚洲在线不卡 | 成人羞羞在线观看网站 | 欧美日韩视频免费 | 我和单位漂亮少妇激情 | 在线观看免费中文字幕 | 在线中文字幕网站 | 亚洲女人被黑人巨大进入 | 久久精品性 | 叶爱在线 | 91网页在线观看 | 熟妇人妻无乱码中文字幕真矢织江 | 国产成人一区 | 久久日本视频 | 激情综合丁香五月 | 日韩精品久久久久久免费 | 日韩欧美精品国产 | 成人久久 | a级黄色小视频 | 人人爱人人搞 | 亚洲欧美第一视频 | 黄色片网站在线播放 | 欧美精品三级 | 91在线视频精品 | 国产做爰全过程免费视频 | 91手机在线视频 | 日韩精品一区二区三区丰满 | 黄色国产片 | 中日韩欧美在线观看 | 久久婷婷激情 | 中国人妖和人妖做爰 | 中文字幕无线码一区 | 成人网站在线进入爽爽爽 | 国产日批视频 | 国产性猛交 | 在线不卡 | 樱花草涩涩www在线播放 | 国产欧美久久久 | av网址有哪些 | 男人天堂亚洲 | 波多野结衣一二三四区 | 成人精品视频在线播放 | 尹人综合| 国产精品毛片久久 | 亚洲一区二区三区四区视频 | 欧美美女啪啪 | 亚洲第一视频在线观看 | av福利在线免费观看 | 爽爽视频在线观看 | 黄色成人毛片 | 久久亚洲无码视频 | 亚洲成人不卡 | 中文字幕无码精品亚洲35 | 欧美三级电影在线观看 | 国产伦精品一区二区三区免费迷 | 国产亚洲一区二区三区四区 | 超鹏在线视频 | 欧美少妇性生活 | www.青青操| 涩涩天堂 | 欧美黄色大片免费看 | 亚洲综合激情五月久久 | 精品一区二区三区免费观看 | 在线观看高h | 亚洲aa视频| 黄色精品在线观看 | 欧美一级淫片免费视频黄 | 黄色一级片一级片 | 无码精品人妻一区二区三区影院 | 91精品国产91综合久久蜜臀 | 欧美日韩h| 好男人www社区 | 国产精品另类 | 欧美做受69| av黄色影院 | 色香影院 | 欧洲美熟女乱又伦 | 日韩五十路 | 97久久国产亚洲精品超碰热 | 视频国产精品 | 成年丰满熟妇午夜免费视频 | 狠狠操2019 | 在线看片成人 | 午夜黄色影院 | 91亚洲欧美 |