編排流程/規則,編排本身也需要很深的邏輯思考!

語言: CN / TW / HK

什麼是流程/規則編排?

所謂編排,就是讓已有的節點通過不同的組織方式完成不同的需求。

首先,我們需要對既有業務做一定程度的抽象,以一個例子開始: 一個簡單的國慶節充值活動:

活動時間 10.1-10.7

充值≥100 元,送 5 元餘額

充值≥50 元,送 10 積分,10.5 之後開始

不疊加送, 即充 100 元只送 5 元餘額不會疊加再送 10 積分

當充值發生時,我們擁有:充值使用者-uid,充值金額-cost,充值時間-time 再有一些製作好的抽象節點,如:

  • 判斷充值≥100 的條件節點 ScoreFlow-100,cost≥100 返回 true,否則返回 false
  • 判斷充值≥50 的條件節點 ScoreFlow-50,cost≥50 返回 true,否則返回 false
  • 發放 5 元餘額的結果節點 AmountResult,結果也可以有返回,比如正常發放了返回 true,庫存不足了等原因導致的沒有發放(不是 error),可以返回 false
  • 發放 10 元積分的結果節點 PointResult

那麼,為什麼要編排,如何編排才是最優的?

為什麼要編排?

遮蔽程式碼影響: 比如編排者只需要知道 AmountResult 是發放餘額的節點,然後在適當的位置執行這個節點即可,不需要關心真實的程式碼邏輯

提升效率: 結合視覺化給非研發人員編排實現業務邏輯,支援動態修改與生效配置,比如充值條件 100 元改成 200,結合視覺化工具直接修改,解放研發,提升生產效率

如何編排?

流程圖式編排

腦海裡最先出現的編排方式,也是最常見的編排方式

執行樹式編排

When X Then Y

以上兩種基本代表了傳統的編排思想,在簡單的例子下,看起來也是非常直觀,但,當變動發生時,尤其是需要靈活調整的場景,他們的表現又如何呢?

變動

①簡單配置修改

充值 100 元改成 80 吧,10 積分變 20 積分吧,時間改成 10.9 號結束吧(**微微一笑,**畢竟我費了這麼大勁,終於體現到價值了!)

②簡單邏輯變動

使用者參與積極性不高啊,去掉不疊加送吧,都送(**稍加思索,**費幾個腦細胞挪一挪還是可以的,怎麼也比改程式碼再上線強吧!)

③進階邏輯變動

5元餘額不能送太多,設定個庫存100個吧,對了,庫存不足了充100元還是得送10積分的哈(**卒…**早知道還不如硬編碼了)

真實線上變動只會更離譜,流程圖式和執行樹式實現的主要缺點在於,牽一髮而動全身,改動一個節點需要瞻前顧後,如果考慮不到位,很容易弄錯,現實的活動內容要比例子複雜的多,時間線也是多條,考慮到這,再加上使用學習框架的成本,往往得不償失,到頭來發現還不如硬編碼

那麼,有沒有更好的編排邏輯?

ice是如何編排的

如圖,ice使用關係節點作為邏輯傳遞的橋樑,用樹圖方式呈現邏輯

關係節點(邏輯節點)

控制業務流轉,如:

AND: 從上到下執行子節點,遇到第一個false中斷並返回false,全部為true則返回true,類似於 Java 的 &&

ANY: 從上到下執行子節點,遇到第一個True中斷並返回true,全部為false則返回false,類似於 Java 的 ||

ALL: 從上到下執行所有子節點

葉子節點(業務節點)

真正做事情的節點,如:

Flow: 一些條件與規則節點,如ScoreFlow

Result: 一些結果性質的節點,如AmountResult,PointResult

None: 一些不會干預流程的節點,如下文會介紹到的TimeChangeNone

執行流程

圖中,如果10月4日,充值100元,則執行流程為:

  1. 從根節點開始,先執行ANY
  2. 充值時間在ANY生效時間內,繼續執行
  3. ANY有兩個子節點,先執行第一個子節點AND
  4. AND有兩個子節點,先執行第一個子節點ScoreFlow-100
  5. ScoreFlow-100判斷並返回true
  6. AND接收到true,繼續向下執行AmountResult
  7. AmountResult發放餘額並返回true
  8. AND子節點執行完畢,接收到兩個true,自己也返回true
  9. ANY接收到true,不再繼續執行子節點並返回true

可以看到,之前需要剝離出的時間,已經融合到各個節點上了,把時間配置還給節點,如果沒到執行時間,如發放積分的節點 10月5日之後才生效,那麼在 10月5日之前,可以理解為這個節點不存在

變動的解決

對於直接修改節點配置就可以

對於直接把ANY 改成 ALL 即可(疊加送與不疊加送的邏輯在這個節點上,屬於這個節點的邏輯就該由這個節點去解決)

對於由於庫存的不足,相當於沒有給使用者發放,則 AmountResult 返回 false,流程還會繼續向下執行,不用做任何更改

再加一個棘手的問題,當時間線複雜時,測試工作以及測試併發要怎麼做?

一個 10月1日開始的活動,一定是在 10月1日之前開發上線完畢,如我在 9月15日要怎麼去測試一個10月1日開始的活動?在 ice 中,只需要稍微修改一下:

增加了個子節點TimeChangeNone(用於更改測試環境請求裡的充值時間,可以改成任意想要的測試時間)

特性

為什麼這麼編排呢?為什麼這樣就能解決這些變動與問題呢?

其實,就是使用樹形結構解耦,流程圖式和執行樹式實現在改動邏輯的時候,需要瞻前顧後,但是 ice 不需要,ice 的業務邏輯都在本節點上,每一個節點都可以代表單一邏輯,比如我改不疊加送變成疊加送這一邏輯就只限制在那個 ANY 節點邏輯上,只要把它改成我想要的邏輯即可,至於子節點有哪些,不用特別在意,節點之間通過上下文傳遞資訊,每個節點執行完的後續流程不需要自己指定

因為自己執行完後的執行流程不再由自己掌控,還可以做到物件級別的複用:

如圖,參與活動這裡用到的 TimeChangeNone,如果現在還有個 H5 頁面需要做呈現,不同的呈現也與時間相關,怎麼辦?只需要在呈現活動這裡使用同一個節點物件(在ice後臺配置中為同id節點),更改其中一個,另一個也會被更新(因為他們是同一個物件,不存在多個複用節點同步問題),避免了到處修改時間

Code

Talk is cheap. Show me the code…

官方文件:http://124.221.148.247/zh/

GitHub:https://github.com/zjn-zjn/ice

Gitee:https://gitee.com/waitmoon/ice

微信公眾號: waitmoon

有更好想法或者更多應用場景或者想一起探討的小夥伴~ 歡迎交流~