供應鏈商品域 DDD 實踐
前言
供應鏈商品域 DDD 實踐時間不長,在實踐過程也碰到了不少問題,有些找到了答案,有些還是在探索中。最近很榮幸受邀在供應鏈服務與創新團隊做了一次分享,也想在這裏把一些經驗和想法分享給大家,藉此拋磚引玉。
DDD 是一套方法論,實踐能否成功,我覺得不僅僅是個技術問題,更是執行貫徹實施的問題。
本文內容主要有兩部分,DDD 基本概念和 DDD 實施。基本概念包括通用語言、分層架構、DDD 要素、邊界上下文,DDD 實施包括領域知識提取方法、思考方式的轉變,在其中會穿插一些商品案例。
一 軟件複雜性是什麼?
在開始 DDD 前,我們應該先回答的一個問題,我們爲什麼需要 DDD?DDD 是複雜軟件應對之道,所以我們來一起看看,軟件的複雜度到底在哪裏?
在阿里兩年,我感受很深的一個點是,我們不能持續交付不斷演進的複雜軟件,所以有 1.0、2.0、3.0 很多的版本,1.0 搞不下去了,開始 2.0,2.0 也搞不下去了,開始 3.0,不斷循環。
阿里體系複雜度我看來是理解力、不可預測、協作力挑戰三個方面。
1 理解力挑戰
-
需求規模龐大,業務數量和類型不斷增多,業務相互耦合,不同業務相互影響。供應鏈有 20 多個行業,經銷、代銷、一盤貨等各種商業模式,有跨境進口、國內業務、國際化業務,這些縱橫導致系統複雜度大幅提升。
-
業務系統多,邊界劃分不清,系統間依賴複雜。如供應鏈商品和共享 SELL、AIC 和 IPM,一直都有邊界問題,一個大項目過來,邊界問題就得討論上好幾天。
-
系統結構複雜,因爲應對高併發、高穩定性等,功能性代碼與非功能性代碼混合,如業務代碼混雜着各種兜底邏輯、灰度邏輯、重試等等,100 行代碼,可能業務代碼不到 30 行。
2 不可預測性挑戰
-
商業環境複雜多變,商業流程、規則多變。商業環境變化快,今年國際化、智能商業路由、考拉融合一下子都來了,在設計上很難前期都規劃好。
-
變化不可預測,軟件系統變化也不可預測,帶來設計挑戰。
3 協作力挑戰
-
大部分需求橫跨多個團隊,需求傳遞低效,需要反覆溝通,方案產出效率低。
-
團隊角色多,業務概念多,沒有統一語言,大家理解容易出現偏差。
二 Why DDD?
DDD 設計合適的領域模型來映射現實中的業務,來有效地解決領域中的核心的複雜問題,是對 OOAD 的擴展和延伸,其解決之道:
-
分而治之,控制規模。
-
關注點分離,應對理解力挑戰,領域模型與存儲模型分離,業務複雜度與技術複雜度分離。
-
分層架構、分離核心,保持結構清晰,應對不可預測性挑戰。
-
統一語言,應對協作力挑戰。
三 DDD 核心
1 通用語言
通用語言是提煉領域知識的產出物,獲得統一語言就是需求分析的過程,也是團隊中各個角色就係統目標、範圍與具體功能達成一致的過程。
領域語言團隊專有,負責解釋和維護,相同名稱概念,跨出這個團隊,理解可以完全不一樣。
領域專家、產品經理、開發人員共同的語言,這種語言是將領域專家和技術人員聯繫在一起的紐帶。
在各種文檔和平時溝通中,保持概念統一,特別提一下,做一箇中文對照, 把概念和代碼連接起來,在代碼做到概念名稱統一,減少混淆。
通用語言價值:
-
定義公共術語,減少概念混淆。
-
溝通達成一致的提前,消除歧義和理解偏差,提升需求和知識消化的效率。
-
概念和代碼的統一語言,連接概念和實現。
2 分層架構
DDD 第二個核心是分層架構,分離模型。優秀的架構應該是什麼樣子?關注點是分離的,可以分而治之,可測試性好。
一個人同時要做多件事情的時候,難免手忙腳亂。代碼也一樣,一段代碼要處理各種事情的時候,也會亂成一團,所以我們要分解開來,各個擊破。
商品域領域模型,在分層架構中的位置,如下:
-
CQRS 模式:領域模型在應用層下面,command 才走領域模型;查詢和搜索服務不走。
-
tunnel 層,對接 db、外部數據資源訪問,領域和模型解耦,類似 DAO。
-
外部通過 SPI 和模型交互,六邊形的 adapter 模式。
3 DDD 要素
1)實體:有 id,有生命週期和狀態。有屬性,有行爲。外部事件會觸發他的行爲和狀態變化。
實體和 vo 的區分,vo 屬性不能修改,使用 final 修飾。vo 爲表達模型減負,如商品有 100 多個屬性,鋪平開不能體現結構化,不能體現分層分類,將相似描述性屬性分組封裝成一個個 vo。
2)爲什麼需要 service,如批量操作多個實體、跨實體操作,如商品複製,轉賬。
商品域的工程架構:
-
serivce 職責是:實體創建,持久化,跨實體操作等。
-
不同層使用不同數據對象,tunnel 使用 dataobjects,面向存儲,需要和實體相互轉換。
-
實體間有關係,可以動態加載關聯對象;dataobjects 只有數據,沒有行爲,一般也不會有關係。
4 邊界上下文
-
邊界 = 域或子域。
-
領域對象在領域內纔有確切的含義。出了這個邊界,不能確保還是這個含義,如蘋果。
-
語言是有上下文的。
-
在不同的上下文中,職責和任務不一樣。人有多個角色,在家裏是爸爸、在公司是小二,職責和任務不一樣。
上下文映射:
-
有了邊界,那麼領域如何輸出價值呢?一個完全封閉的系統沒有任何價值。
-
常用的方式有:共享內核,防腐層等。防腐層:商品上游提供 spi,spi 不是直接對外開放領域模型,建立一層開放視圖。採購域建立防腐層,收口商品的變更對本域影響。
四 DDD 實施
1 DDD 實施的挑戰
-
識別和提煉領域知識,並體現在模型代碼上,強調一次 “並體現在模型代碼上”!
-
防腐,保持模型不斷演進,需要持續投入,保證 DDD 貫徹執行。
-
人的轉變,開發思考方式的轉變。
2 什麼是領域知識?
領域知識有分層分類,平臺通用商業規則,是領域模型主要輸入,商家個性化不能下沉到領域模型層。
3 領域知識提煉,需求和鏈路 5W1H 分析法
兩階段分析:用戶故事、鏈路和邊界分析。
-
前 3W 描寫用戶故事,用戶要什麼,爲什麼要?舉個例子,我作爲採購小二,需要商品庫存爲 0 自動下架,因爲有超賣風險,客戶會投訴。
-
後面的 When、Where、How 是鏈路和邊界分析,觸發的條件是什麼,要實現這個功能需要哪些域參與進來,分別提供什麼能力?
通過這個分析,獲取用戶需求,和全鏈路分工。
4 領域知識提煉,結構化分析
-
APP 層至上而下過程分析,模型層自下而上分析相結合。
-
能力下沉保持模型不斷演進,能力下沉標準:複用、內聚。
5 思考方式的轉變
領域驅動,在模型階段不會關注數據設計、不會關注存儲、不會關注消息怎麼發,業務和技術視角關注點做了分離。
五 商品域實踐相關
商品域工程架構:
最後,保持模型不斷演進!!!
商品域模型更新 readme,保持模型不斷演進。否則會 APP 層會越來越大,模型層越來越小,最後頭重腳輕,領域坍塌了。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/oEotZ9Sueus-LGZWPoy_RQ