天天看點

開發業務邏輯

作為一個研發,我們工作中都會處理面臨下面這些困惑:

又加需求,一個方法本來就處理了 300 行,現在又加 50 行。

狀态邏輯太多了,産品第 2 期又加了一個邏輯,代碼結構要調整,很頭疼。

每個人都在吐槽,業務研發在工作中處理最多的就是 if else,好不容易寫個 switch 都能給同僚吹一周。以上三個場景應該是日常需求疊代優化中面臨最多的場景了,作為一個自稱編碼水準較高的人,總結了以下三個真實的場景,給出一些可選的方案。

梳理産品邏輯中的主流程節點,整理節點所需要的依賴資料已經節點觸發後對應的業務邏輯。類比​​消息隊列​​,也是不同的業務方訂閱自己的事件源,進行不同的處理。不同點在于一個是分布式,一個是本文描述單機業務處理場景。

舉一個使用者注冊之後的場景,需要:

發​​短信​​

發優惠券 如果使用者注冊成功之後,直接發了mq消息,那麼使用者系統和券系統分别訂閱這個消息進行處理。不過這裡讨論的是在一個項目子產品中處理完所有相關的邏輯。

代碼将在 ​<code>​UserRegistered()​</code>​ 中一步一步去處理邏輯,之後需求又加入了 初始化A資料和初始化B資料 兩個需求,實作也會落到這個方法之後,最後整個代碼會越來越臃腫。

開發業務邏輯

接下來用事件訂閱模型去化解這個點,非常實用,一點都不華麗,代碼也很好讀懂。

開發業務邏輯

最後對應到程式代碼可能是這樣的:

後面的疊代維護中,隻要主流程不發生變化,那麼相應的邏輯隻需要去增加訂閱者去實作。

在業務邏輯資料處理這一層,很多的業務場景都與資料扭轉狀态有關,并且最後會有相應的資料實體相映射。比如我們常見的:

各種商品訂單(天貓,淘寶,外賣)

工作流(審批,工單處理)

這類需求的特點是,讀寫場景QPS不高,對資料的準确一緻性要求非常高。我們底層一般直接存儲到​​資料庫​​,之上加一層簡單的資料緩存就能處理。

面臨的主要問題是,狀态太多難以維護,應該還會出現狀态的調整比如特殊場景下的狀态A到狀态Z的扭轉。

不過業内早已給出了比較通用的解決方案,有限狀态機。下面我們列舉一個簡單的訂單狀态扭轉邏輯:

開發業務邏輯

如果設計到狀态相關的調整,在狀态機定義的地方去修改就可以解決問題。和事件訂閱非常相識,也是集中維護,同一管理。

軟體工程沒有銀彈 --布魯克斯

軟體開發中我們遇到的一個一個需求都是不可預測的,我們确實很難找到一種終極的解決方案。不過本文中的讨論局限在業務邏輯開發的開發套路。那麼,n元組這個簡單的概念可能算得上一顆銀彈。不管業務邏輯有多複雜,在理論上我們都能抽象出n個字段來表達我們的資料模型。

拿一個訂單舉例子,我們有如上訂單特征。不可避免的,每一個業務場景,每一個邏輯,産品邏輯都可能有自己的配置和相應的處理流程,且這些邏輯都是業務疊代優化的重災區,比如:

江浙滬地區包郵

某一批固定的城市需要打8.8折

雨天調價格

法定節假日打烊不服務

vip身份的使用者展示文案特殊處理

每一個開發同學都曾被這些邏輯折磨的異常痛苦,這裡給出一個抽象的方案,最終每一個訂單特征都會落到具體的業務處理類,所有的類都實作該業務場景的 interface,主流程隻需要構造 n元組然後擷取到相應的 interface 之後進行調用。

開發業務邏輯

n元組的概念其實早已經滲透到了開發中的每一個角落,我們需要做的事情就是,在業務開發的時候真正的去思考這一層資料模型,然後加以運用,最後的代碼一定不那麼 if else。

以上三闆斧在業務中使用可以很輕,也可以很重。這就意味着我們能自己寫一個簡單夠用的(對于你完全了解成長有限的業務場景),或者找一個star多且在維護的開源方案(對于有潛力,未來大有可為的業務)來代替。同時,這些編碼套路在各種場景下都能非常靈活的組合,比如:

訂單狀态更新後觸發事件(狀态機+事件訂閱)

不同業務線,狀态機配置,初始化放松不同(n元組+狀态機)

不得不提到的一點,在漫長的業務疊代中,産品文檔會越來越缺失,最終隻有通過代碼才能了解線上的真正邏輯(有時間代碼過于複雜,可能就沒有人知道線上的具體情況了),集中配置,統一維護的意義之一就在于此。相信做過複雜曆史系統的交接或重構的同學對這一點都深有體會。