
作者 | 側帽
來源 | 阿裡技術公衆号
前言
供應鍊商品域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等相關知識。
點選這裡,開始學習吧~