作者 | 側帽
來源 | 阿里技術公眾號
前言
供應鏈商品域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層會越來越大,模型層越來越小,最後頭重腳輕,領域坍塌了。
微服務實戰技術圖譜
由微服務實戰課程專家組出品,基於熱門的微服務技術棧Spring Cloud Alibaba、Nacos,結合阿里巴巴工程師的一線實戰經驗,涵蓋服務發現、服務配置、服務調用、服務熔斷和Service Mesh等相關知識。
點擊這裡,開始學習吧~