開發與維運

供應鏈商品域DDD實踐

image.png

作者 | 側帽
來源 | 阿里技術公眾號

前言

供應鏈商品域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核心

image.png

1 通用語言

通用語言是提煉領域知識的產出物,獲得統一語言就是需求分析的過程,也是團隊中各個角色就係統目標、範圍與具體功能達成一致的過程。

領域語言團隊專有,負責解釋和維護,相同名稱概念,跨出這個團隊,理解可以完全不一樣。

領域專家、產品經理、開發人員共同的語言,這種語言是將領域專家和技術人員聯繫在一起的紐帶。

在各種文檔和平時溝通中,保持概念統一,特別提一下,做一箇中文對照, 把概念和代碼連接起來,在代碼做到概念名稱統一,減少混淆。

通用語言價值:

  • 定義公共術語,減少概念混淆。
  • 溝通達成一致的提前,消除歧義和理解偏差,提升需求和知識消化的效率。
  • 概念和代碼的統一語言,連接概念和實現。

image.png

2 分層架構

DDD第二個核心是分層架構,分離模型。優秀的架構應該是什麼樣子?關注點是分離的,可以分而治之,可測試性好。

一個人同時要做多件事情的時候,難免手忙腳亂。代碼也一樣,一段代碼要處理各種事情的時候,也會亂成一團,所以我們要分解開來,各個擊破。

image.png

商品域領域模型,在分層架構中的位置,如下:

image.png

  • CQRS模式:領域模型在應用層下面,command才走領域模型;查詢和搜索服務不走。
  • tunnel層,對接db、外部數據資源訪問,領域和模型解耦,類似DAO。
  • 外部通過SPI和模型交互,六邊形的adapter模式。

3 DDD要素

1)實體:有id,有生命週期和狀態。有屬性,有行為。外部事件會觸發他的行為和狀態變化。

實體和vo的區分,vo屬性不能修改,使用final修飾。vo為表達模型減負,如商品有100多個屬性,鋪平開不能體現結構化,不能體現分層分類,將相似描述性屬性分組封裝成一個個vo。

2)為什麼需要service,如批量操作多個實體、跨實體操作,如商品複製,轉賬。

商品域的工程架構:

  • serivce職責是:實體創建,持久化,跨實體操作等。
  • 不同層使用不同數據對象,tunnel使用dataobjects,面向存儲,需要和實體相互轉換。
  • 實體間有關係,可以動態加載關聯對象;dataobjects只有數據,沒有行為,一般也不會有關係。

image.png

4 邊界上下文

  • 邊界 = 域或子域。
  • 領域對象在領域內才有確切的含義。出了這個邊界,不能確保還是這個含義,如蘋果。
  • 語言是有上下文的。
  • 在不同的上下文中,職責和任務不一樣。人有多個角色,在家裡是爸爸、在公司是小二,職責和任務不一樣。

image.png

上下文映射:

  • 有了邊界,那麼領域如何輸出價值呢?一個完全封閉的系統沒有任何價值。
  • 常用的方式有:共享內核,防腐層等。防腐層:商品上游提供spi,spi不是直接對外開放領域模型,建立一層開放視圖。採購域建立防腐層,收口商品的變更對本域影響。

image.png

四 DDD實施

1 DDD實施的挑戰

  • 識別和提煉領域知識,並體現在模型代碼上,強調一次“並體現在模型代碼上”!
  • 防腐,保持模型不斷演進,需要持續投入,保證DDD貫徹執行。
  • 人的轉變,開發思考方式的轉變。

image.png

2 什麼是領域知識?

領域知識有分層分類,平臺通用商業規則,是領域模型主要輸入,商家個性化不能下沉到領域模型層。

image.png

3 領域知識提煉,需求和鏈路5W1H分析法

兩階段分析:用戶故事、鏈路和邊界分析。

  • 前3W描寫用戶故事,用戶要什麼,為什麼要?舉個例子,我作為採購小二,需要商品庫存為0自動下架,因為有超賣風險,客戶會投訴。
  • 後面的When、Where、How是鏈路和邊界分析,觸發的條件是什麼,要實現這個功能需要哪些域參與進來,分別提供什麼能力?

通過這個分析,獲取用戶需求,和全鏈路分工。

image.png

4 領域知識提煉,結構化分析

  • APP層至上而下過程分析,模型層自下而上分析相結合。
  • 能力下沉保持模型不斷演進,能力下沉標準:複用、內聚。

image.png

5 思考方式的轉變

領域驅動,在模型階段不會關注數據設計、不會關注存儲、不會關注消息怎麼發,業務和技術視角關注點做了分離。

image.png

五 商品域實踐相關

商品域工程架構:

image.png

image.png

最後,保持模型不斷演進!!!

商品域模型更新readme,保持模型不斷演進。否則會APP層會越來越大,模型層越來越小,最後頭重腳輕,領域坍塌了。

image.png


微服務實戰技術圖譜

由微服務實戰課程專家組出品,基於熱門的微服務技術棧Spring Cloud Alibaba、Nacos,結合阿里巴巴工程師的一線實戰經驗,涵蓋服務發現、服務配置、服務調用、服務熔斷和Service Mesh等相關知識。

點擊這裡,開始學習吧~

Leave a Reply

Your email address will not be published. Required fields are marked *