基於狀態機的訂單系統

2021-08-20 08:17:47 字數 2986 閱讀 3685

前言: 本文針對民宿業務下訂單系統狀態管理提出了一種解決方案:通過有限狀態機極大的簡化訂單狀態的遷移處理,同時使訂單狀態變得可控。此處的狀態機指「有限狀態機」

有限狀態機(英語:finite-state machine,縮寫:fsm)又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型 摘自 - 維基百科

fsm(有限狀態機)可以使用狀態圖(或狀態轉移圖)來表示。此外可以使用多種型別的狀態轉移表。下面展示最常見的表示:當前狀態(b)和條件(y)的組合指示出下乙個狀態(c)。完整的動作資訊可以只使用腳注來增加。包括完整動作資訊的fsm定義可以使用狀態表。

| 當前狀態→ 

條件↓| 狀態a | 狀態b|狀態c|

| ------------- |:-------------:| -----:|

| 條件x | ... |...|...|

| 條件y | ... | 狀態c| ... |

| 條件z| ...| ...| ... |

民宿作為新興的一種住宿業態與酒店的預定機制不同,民宿的房東會根據房客的基本情況決定是否允許房客入住,即房東要確認房客的訂單才能成交。

民宿訂單系統作為中間平台既要支撐**售賣方對自營**的售賣又要支援對**商**的售賣;又要同時作為**提供商將**進行分銷。

另外,為了考慮房客感受,訂單系統要支付1)先支付後確認;2) 先確認後支付兩種下單模式。

在複雜的業務背景下導致訂單的狀態比較多且狀態的流轉複雜,訂單狀態變化的觸發點非常多。

由於考慮到之後民宿業務的擴充套件(比如可能接入保險等業務),訂單設計時採用訂單項的方式。orderheader表示訂單頭資訊,每個業務儲存在orderitem中作為訂單項存在。

針對民宿的業務場景設計出訂單的狀態如下:

主訂單(orderheader)狀態列舉

**業務子訂單(spaceorderitem)列舉

**訂單狀態可以拆分為支付線和業務線來看,前半部分代表支付狀態,後半部分代表業務狀態。支付狀態和業務狀態的列舉做笛卡爾積是邏輯上可能存在的所有狀態列表。實際中只有下面的狀態才是合法狀態。

待支付待下單

訂單狀態的觸發場景列舉. 下面的列舉場景是經過抽象的,實際業務場景中遠遠多於下面的7種

建立訂單

訂單狀態被觸發時除了上面列舉的觸發場景,還要結合當時訂單的具體形態,比如是否為分銷訂單、是否為詢單模式等綜合判斷。影響訂單狀態判斷的條件列舉如下:

是否已經支付

考慮到上面列舉的各種訂單狀態型別以及複雜的訂單狀態變遷觸發節點(上面列舉了7種,實際業務場景中要多得多),如果將訂單狀態的變化分步到具體每個觸發的事件中會導致訂單狀態變化的不可控且極易導致狀態變化的混亂。

此外,狀態的遷移變化,請自行補腦 if... else ...

狀態遷移圖.jpg

orderfsm類

封裝狀態機的三個要素1)狀態 2)事件 3)動作

/**

* 訂單簡明狀態機

* * @author

jeff

* @version 2017/1/22 13:37

*/public

class

orderfsm

public

orderfsm

(orderfsmcontextdata contextdata)

public orderfsm fire

(fsmevent event)

throws tongaexception

return fsm;

}public spaceorderfsmstate getfsmspacestate

() public

enum spaceorderfsmstate

public

enum fsmevent

//以訂單建立為例

private orderfsm ordercreate

(orderfsmcontextdata contextdata)

throws tongaexception

//分銷

if (contextdata.isdistribute()) else

} else

return

this;

}... 略...

}

orderfsmcontextdata儲存狀態機的上下文資訊
用於具體狀態變遷時的邏輯判斷

/**

* 訂單簡明狀態機上下文資料

* * @author

jeff

* @version 2017/1/22 13:40

*/public

class

orderfsmcontextdata

public

boolean

ispayed

() public

boolean

isdistribute

() public

boolean

isselfsupport

() public

boolean

isinquiry

()}

訂單狀態機使用

//狀態機獲取子訂單狀態id

orderfsm fsm = orderfsm.init(

new orderfsmcontextdata(支付成功?,

分銷訂單?,

自營產品?,

詢單模式?

)).fire(orderfsm.fsmevent.order_create);

基於時間系統的狀態機

1根據各任務的週期執行時間確定輪詢間隔,注意 輪詢時間間隔只能比任務執行時間稍長,但一定不能斷 2 用乙個定時器,基準定時為各任務的最小公倍數 軟體計數器累加從而觸發各任務標誌 對任務進行位元組編碼 3主函式中分別操作 toggle task 設定各標誌,這裡可以是非時間觸發的事件 slect ta...

基於狀態機的按鍵程式

基於狀態機的按鍵程式 一般的按鍵輸入軟體介面程式非常簡單,在程式中一旦檢測到按鍵輸入口為低電平 有時可能為高 便採用軟體延時的方法來進行消抖,然後再次檢測按鍵輸入,如果再次確認為低電平則表示有按鍵按下,轉入執行按鍵處理程式。如果延時後檢測的電平為高電平則放棄本次按鍵檢測,重新開始一次按鍵檢測過程。在...

基於狀態機的遊戲框架

有限狀態機就是乙個具有有限數量狀態,並且能夠根據相應的操作從乙個狀態變換到另乙個狀態,而在同一時刻只能處在一種狀態下的智慧型體。英文 finite state machine 簡稱 fsm 最簡單的狀態機 if else 實際上if else就是乙個最有兩種狀態的狀態機,分別是true和false ...