基於狀態機的訂單系統
前言: 本文針對民宿業務下訂單系統狀態管理提出了一種解決方案:通過有限狀態機極大的簡化訂單狀態的遷移處理,同時使訂單狀態變得可控。此處的狀態機指“有限狀態機”
1 有限狀態機的概念
有限狀態機(英語:finite-state machine,縮寫:FSM)又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型 摘自 - 維基百科
FSM(有限狀態機)可以使用狀態圖(或狀態轉移圖)來表示。此外可以使用多種型別的狀態轉移表。下面展示最常見的表示:當前狀態(B)和條件(Y)的組合指示出下一個狀態(C)。完整的動作資訊可以只使用腳註來增加。包括完整動作資訊的FSM定義可以使用
| 當前狀態→
條件↓| 狀態A | 狀態B|狀態C|
| ------------- |:-------------:| -----:|
| 條件X | ... |...|...|
| 條件Y | ... | 狀態C| ... |
| 條件Z| ...| ...| ... |
2 民宿業務背景
民宿作為新興的一種住宿業態與酒店的預定機制不同,民宿的房東會根據房客的基本情況決定是否允許房客入住,即房東要確認房客的訂單才能成交。
民宿訂單系統作為中間平臺既要支撐房源售賣方對自營房源的售賣又要支援對供應商房源的售賣;又要同時作為房源提供商將房源進行分銷。
另外,為了考慮房客感受,訂單系統要支付1)先支付後確認;2) 先確認後支付兩種下單模式。
在複雜的業務背景下導致訂單的狀態比較多且狀態的流轉複雜,訂單狀態變化的觸發點非常多。
3 民宿業業務下的訂單狀態
由於考慮到之後民宿業務的擴充套件(比如可能接入保險等業務),訂單設計時採用訂單項的方式。OrderHeader表示訂單頭資訊,每個業務儲存在OrderItem中作為訂單項存在。
針對民宿的業務場景設計出訂單的狀態如下:
主訂單(OrderHeader)狀態列舉
- 處理中
- 成功
- 失敗
- 訂單取消
- 訂單部分取消
- 訂單完成
- 訂單關閉
房源業務子訂單(SpaceOrderItem)列舉
房源訂單狀態可以拆分為支付線和業務線來看,前半部分代表支付狀態,後半部分代表業務狀態。支付狀態和業務狀態的列舉做笛卡爾積是邏輯上可能存在的所有狀態列表。實際中只有下面的狀態才是合法狀態。
- 待支付待下單
- 待支付下單失敗
- 待支付待確認
- 待支付已確認
- 待支付確認失敗(拒單)
- 待支付確認失敗(超時)
- 待支付已退訂
- 已支付待下單
- 已支付待確認
- 已支付已確認
- 待退款下單失敗
- 待退款確認失敗(拒單)
- 待退款確認失敗(超時)
- 待退款已退訂
- 待退款部分退訂
- 部分退款部分退訂
- 部分退款已確認
- 已退款下單失敗
- 已退款確認失敗(拒單)
- 已退款確認失敗(超時)
- 已退款已退訂
訂單狀態的觸發場景列舉. 下面的列舉場景是經過抽象的,實際業務場景中遠遠多於下面的7種
- 建立訂單
- 訂單支付成功
- 訂單退款成功
- 訂單被主動拒絕
- 訂單被主動接受
- 訂單確認超時
- 訂單被主動取消
訂單狀態被觸發時除了上面列舉的觸發場景,還要結合當時訂單的具體形態,比如是否為分銷訂單、是否為詢單模式等綜合判斷。影響訂單狀態判斷的條件列舉如下:
- 是否已經支付
- 是否為分銷訂單
- 是否為自營訂單
- 是否為詢單模式
4 使用FSM對狀態進行優化
考慮到上面列舉的各種訂單狀態型別以及複雜的訂單狀態變遷觸發節點(上面枚舉了7種,實際業務場景中要多得多),如果將訂單狀態的變化分步到具體每個觸發的事件中會導致訂單狀態變化的不可控且極易導致狀態變化的混亂。
此外,狀態的遷移變化,請自行補腦 if... else ...
4.1 民宿訂單狀態轉移表(部分)
狀態遷移圖.jpg4.2 Java 實現民宿訂單FSM(部分,僅做說明使用)
OrderFSM類
封裝狀態機的三個要素1)狀態 2)事件 3)動作
/**
* 訂單簡明狀態機
*
* @author <a href="[email protected]">jeff</a>
* @version 2017/1/22 13:37
*/
public class OrderFSM {
private SpaceOrderFSMState fsmSpaceState = SpaceOrderFSMState.NOPAY_NOORDER;
private OrderFSMContextData contextData;
public static OrderFSM init(OrderFSMContextData contextData) {
return new OrderFSM(contextData);
}
public OrderFSM(OrderFSMContextData contextData) {
this.contextData = contextData;
}
public OrderFSM fire(FSMEvent event) throws TongaException {
OrderFSM fsm = null;
switch (event) {
case ORDER_CREATE:
fsm = orderCreate(contextData);
break;
...略...
default:
throw new TongaException("訂單FSM不支援的事件型別");
}
return fsm;
}
public SpaceOrderFSMState getFsmSpaceState() {
return fsmSpaceState;
}
public enum SpaceOrderFSMState {
NOPAY_NOORDER(1020, "待支付待下單"),
NOPAY_ORDERFAILED(1023, "待支付下單失敗"),
NOPAY_NOCONFIRM(1010, "待支付待確認"),
... 略...
}
public enum FSMEvent {
ORDER_CREATE, //訂單建立
BUSINOTIFY_ORDERFAILED,//業務結果通知,下單失敗
... 略...
}
//以訂單建立為例
private OrderFSM orderCreate(OrderFSMContextData contextData) throws TongaException {
if (fsmSpaceState != SpaceOrderFSMState.NOPAY_NOORDER) {
throw new TongaException(ResultCodeEnum.OTHER_ERROR, "FSM:當前狀態不允許 ORDER_CREATE 事件");
}
//分銷
if (contextData.isDistribute()) {
if (contextData.isPayed()) {
this.fsmSpaceState = contextData.isSelfSupport() ? SpaceOrderFSMState.PAYED_NOCONFIRM : SpaceOrderFSMState.PAYED_NOORDER;
} else {
this.fsmSpaceState = contextData.isSelfSupport() ? SpaceOrderFSMState.NOPAY_NOCONFIRM : SpaceOrderFSMState.NOPAY_NOORDER;
}
} else {
//非分銷
this.fsmSpaceState = contextData.isSelfSupport() ? SpaceOrderFSMState.NOPAY_NOCONFIRM : SpaceOrderFSMState.NOPAY_NOORDER;
}
return this;
}
... 略...
}
OrderFSMContextData儲存狀態機的上下文資訊
用於具體狀態變遷時的邏輯判斷
/**
* 訂單簡明狀態機上下文資料
*
* @author <a href="[email protected]">jeff</a>
* @version 2017/1/22 13:40
*/
public class OrderFSMContextData {
private boolean isPayed;//是否已經支付成功
private boolean isDistribute;//是否為分銷
private boolean isSelfSupport;//是否自營
private boolean isInquiry;//是否詢單
public OrderFSMContextData(boolean isPayed, boolean isDistribute, boolean isSelfSupport, boolean isInquiry) {
this.isPayed = isPayed;
this.isDistribute = isDistribute;
this.isSelfSupport = isSelfSupport;
this.isInquiry = isInquiry;
}
public boolean isPayed() {
return isPayed;
}
public boolean isDistribute() {
return isDistribute;
}
public boolean isSelfSupport() {
return isSelfSupport;
}
public boolean isInquiry() {
return isInquiry;
}
}
訂單狀態機使用
//狀態機獲取子訂單狀態ID
OrderFSM fsm = OrderFSM.init(
new OrderFSMContextData(支付成功?,
分銷訂單?,
自營產品?,
詢單模式?
)).fire(OrderFSM.FSMEvent.ORDER_CREATE);
相關推薦
基於狀態機的訂單系統
前言: 本文針對民宿業務下訂單系統狀態管理提出了一種解決方案:通過有限狀態機極大的簡化訂單狀態的遷移處理,同時使訂單狀態變得可控。此處的狀態機指“有限狀態機”1 有限狀態機的概念有限狀態機(英語:finite-state machine,縮寫:FSM)又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些
基於有限狀態機在Unity3D中實現的簡單搓招系統
在諸如街霸、拳皇等格鬥遊戲中,搓招指的是玩家通過在短時間內連續輸入特定的指令來釋放角色的招式(比如右下右拳釋放升龍拳) 那麼如何通過狀態機來實現搓招呢? 我們可以讓每個招式都持有一個狀態機,把這個招式要求的輸入指令作為狀態機的狀態而存在。依然以升龍拳為例,我們可以
基於mealy狀態機的密碼鎖系統設計
應學院課程安排學習了verilog語言並在Xilinx vivado下用暫存器傳輸級的verilog 程式碼做功能實現,最後在basys3開發板上作驗證與測試。 一、FPGA基本介紹 FPGA(Field-Programmable Gate Array),即現場可程式設計
基於有窮狀態機思想的電梯系統
# 介紹 這次設計的電梯系統是一次軟體工程的小組作業~~(這門課沒安排實驗,佛)~~,我在這次小組作業中負責的是後端設計和演算法設計的部分,多虧了想出來了~~(不然只能CV了,其實我是這個系統的產品經理~~ 專案上傳到了[GitHub](https://github.com/ginkgo-code/elev
基於虛擬機的CentOS7系統的IP配置
網絡服務 ip地址 虛擬機 編輯器 動態 dhclient #自動獲取動態IP ip add #獲取ip地址將動態IP修改為靜態IP(步驟):vi /etc/sysconfig/network-scripts/ifcfg-ens33 按小寫字母“i”,進入編輯模式然後增加或改變以下內容:
【slighttpd】基於lighttpd架構的Server專案實戰(8)—狀態機機制回顧
轉載地址:https://blog.csdn.net/jiange_zh/article/details/50640270 有限狀態機FSM(Finite State Machine) 關於狀態機的一個極度確切的描述是它是一個有向圖形,由一組節點和一組相應的轉移函式組成。狀態機通過響應一系列
基於委託與事件的有限狀態機設計與實現(Unity3d)
有限狀態機設計與實現 前言 最近看到一句話,就是優秀是一種習慣,所以突然就總想寫點什麼,當作是遊戲開發這條路上的學習筆記吧,另外也時刻提醒自己需要不斷努力。 什麼是狀態機? 先貼百度百科的概念內容吧: 有限狀態機,(英語:Finite-state machine
Unity3d實現有限狀態機系統
在之前有過介紹一個視覺化有限狀態機編輯器外掛PlayerMaker在這裡也可以在我們的程式碼中實現一個狀態機首先建立一個指令碼,來管理我們的各個狀態using System.Collections; using System.Collections.Generic; usin
基於FPGA的影象處理(五)--狀態機
使用FPGA實現各種演算法時,狀態機是很常用的方法,在SysGen中有兩種非常簡便的方法構建狀態機,一是使用Mcode,以switch-case語句輕鬆實現,二是使用SysGen自帶狀態機模組。 狀態機 假設我們要從01序列中檢測出1011序列,則
嵌入式系統中的狀態機設計心得
在使用iTRON類OS的嵌入式系統中,除了驅動程式以外,大多數模組也就是中介軟體和應用程式是以任務(TASK)的形式設計的。而iTRON類OS大多采用C語言實現,於是用狀態機的方式實現功能模組成為了主要的設計方法。 至於說面向物件,只要是稍微嚴謹一點的嵌入式系統,設計上要求程式完全覆蓋所有的可能情況。程式不
基於QT的全自動超聲波焊接機上位機追溯系統(已經在裝置上應用)
應用說明:本上位機程式是我在做鋰電池產線專案的時候開發的,用於採集裝置資料以及實現裝置自動控制,下位機採用基恩士PLC,超聲波機採用上海一家的超聲波焊接機,實現電芯極耳的自動焊接,上位在裝置焊接過程中記錄焊接資料,同時監控裝置異常。主要功能有:@1.裝置監控;@2.PLC TCP/IP通訊;@3超聲波焊接機通
解決VMware10虛擬機客戶機操作系統無蘋果MacOSX
cbe ima step html -s index -a macos get 安裝完VMwareWorkstation10.0.3虛擬機,滿心希望安裝蘋果系統MAC OS X 10.9 Mavericks玩一把,卻發現VMware10虛擬機客戶機操作系統選項裏並沒
geek青年的狀態機,查表,純C語言實現
fill south 總結 target 堅持 str 分享 接收 backward geek青年的狀態機,查表,純C語言實現 1. 問題的提出。抽象 建一,不止是他,不少人跟我討論過這種問題:怎樣才幹保證在需求變更、擴充的情況下。程序的主體部分不動呢? 這是一個
VMware12提示 已將該虛擬機配置為使用 64 位客戶機操作系統。但是,無法執行 64 位操作。
http 操作 技術分享 步驟 啟動 如果 sdn 重啟 cpu VMware12提示 已將該虛擬機配置為使用 64 位客戶機操作系統。但是,無法執行 64 位操作。 此主機支持 Intel VT-x,但 Intel VT-x 處於禁用狀態 解決辦法: 下
基於本地文件系統的LocalDB
root 構造函數 -s oot region pan pri 指定 void 零、前言 之前寫一些小工具的時候,需要用到數據存儲方面的技術,但是用數據庫又覺得太大了,本地文件存儲txt文件存儲又不是很規範,於是乎想到了去編寫一個簡單的基於本地文件系統的數據存儲庫,暫且
虛擬機 liunx系統以 root 身份登錄權限
text .cn guest sig list 編輯 blog session fix 開啟虛擬機 打開終端開啟root賬戶 :sudo passwd -u root 輸入當前用戶的密碼 為root賬戶設置密碼:sudo passwd root
卅川的狀態機之路(創作中,不定時上傳)
rom 不同的 大學 核心 追溯 選擇 有限狀態機 span 任務 川的第一篇幹貨,將從講述FSM(有限狀態機)開始。 川第一次接觸狀態機這種東西,還得追溯到剛到暢遊工作,破解了別的遊戲的代碼(遊戲程序就是這麽沒節操和底線,嗯!)才知道有這麽個東西的。雖然大學學習過相
FSM(狀態機)、HFSM(分層狀態機)、BT(行為樹)的區別
分類 log 巡邏 其中 感到 人工智能 執行者 跳轉 藍色 遊戲人工智能AI中最常聽見的就是這三個詞: FSM 這個不用說拉,百度一大堆解釋, 簡單將就是將遊戲AI行為分為一個一個的狀態,狀態與狀態之間的過渡通過事件的觸發來形成。 比如士兵的行為有“巡邏”,“追擊敵人”,
虛擬機Linux系統下配置網絡
ctrl+ size enc 代碼 網絡 sco 高級 loop 驅動 虛擬機上安裝Redhat9.0後是沒有網絡的,而本來的Windows系統是可以上網的,此時想在Redhat上網就需要在Linux系統上配置網絡,以下是筆者自己配置的一點心得. 1.電腦本機系統打開網絡
AI 狀態機機制(虛幻三的做法)
調用 設有 mode 作用 self 信息 怪物 測試 pat 1.Nav Mesh Bounds Volume (Navigate導航,操縱)指的是可以導航(操作)的區域。 2.MVC的編程模式:(Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。 通