DDD的函數語言程式設計實現

公众号-JavaEdge發表於2024-08-21

DDD是一種成熟的軟體設計方法,旨在確保領域專家和開發人員能夠有效合作,創造出高質量的軟體。

本文介紹咋將FP(函數語言程式設計)應用於DDD的實現,使其既優雅又簡潔。C4模型中,軟體架構圖分為四個層次:“系統上下文”、“容器”、“元件”和“程式碼”。

“元件”是構成容器的基本單位,也是本文描述的層次。

1 程式碼組織結構

隨應用程式複雜性增加,管理這種複雜性的一種方法是根據應用程式的職責或關注點將其拆分。分層架構是一種遵循這一原則的方法,它有助於保持不斷增長的程式碼庫的組織性,使開發人員能夠輕鬆找到某個功能的實現位置。

分層架構中,程式碼被水平拆分為不同的層次,每一層透過物件導向(OO)設計進行封裝。請求從頂層進入,程式碼從上到下執行,輸出從頂層產生。

這種設計的一個問題是,多個層次不僅分離了關注點,還將同一業務功能的上下文分離到不同的位置,這意味著在修改同一業務功能時,可能需要同時修改多個層次。

另一個問題是,表示層和應用層通常被設計為外觀模式,這易導致上帝物件的出現,而上帝物件被認為是一種反模式

FP本質是組合。FP更傾向於垂直組織程式碼,而不是水平拆分程式碼。多個函式透過Monad組合成一個函式流水線來實現一個業務功能(通常是一個API)。

基於函數語言程式設計的垂直程式碼結構:

2 信任邊界

現實世界中,問題域之間的邊界是模糊的。限界上下文是計算機系統中對現實世界問題的人工投影:

  • 邊界之外的世界不可信,因為它包括來自使用者的各種輸入
  • 邊界之內的世界則是可信的、合法的、共享的領域模型

這要求我們在限界上下文的邊界處引入驗證和轉換,從而防止外部輸入並驗證輸出的合法性。

常見的驗證和轉換包括:

  • 將輸入資料轉換為領域模型
  • 驗證輸入資料的有效性,例如確保使用者名稱和電子郵件不為空
  • 輸出檢查器,防止如使用者密碼等敏感資訊被包含在輸出資料中

在FP中,Applicative通常用於驗證和轉換輸入資料為領域模型。一旦輸入資料突破信任邊界,你就無需擔心使用者名稱是否為空或電子郵件格式是否正確。你應專注於使用ADT進行領域建模,並透過純函式處理業務規則。

3 使用狀態機進行領域建模

業務模型可以透過不同狀態的轉換來建模。你總是可以透過聯合型別(和型別)將領域建模為狀態機。另一個好處是,在FP中,模式匹配迫使你處理聯合型別的每個分支,以避免遺漏情況。

狀態之間的轉換

以使用者註冊為例:註冊可以分為三個步驟:

  • 輸入使用者名稱和密碼
  • 驗證電子郵件
  • 支付會員費

這三個步驟可以透過聯合型別記錄為三個明確的狀態。諸如註冊、新增電子郵件、驗證電子郵件等行為可以透過對這個領域模型進行模式匹配設計為函式。

4 保持領域純粹

遵循依賴倒置原則的應用程式傾向於實現洋蔥架構或整潔架構。其核心思想是將業務邏輯和領域模型置於應用程式的中心,而不是讓業務邏輯依賴於資料訪問或其他基礎設施。依賴關係被倒置:基礎設施和實現細節依賴於應用程式核心。

同樣,在FP中,我們傾向於在每個API請求中將函式組合為流水線。與洋蔥架構類似,我們儘可能將副作用置於領域之外,以保持領域的純粹性。純函式遵循永續性無知原則,它們專注於實現業務規則。

洋蔥架構:

5 總結

通常,物件導向程式語言是實現DDD的首選,函數語言程式設計則被認為適合資料科學的管道處理。實際上,DDD只是一個強調應專注於領域的思想,它並不依附於任何特定的程式設計正規化。你可以利用FP的特性,如可組合性、Monad、Applicative和模式匹配,在“元件”架構層級上實現DDD。

關注我,緊跟本系列專欄文章,咱們下篇再續!

作者簡介:魔都架構師,多家大廠後端一線研發經驗,在分散式系統設計、資料平臺架構和AI應用開發等領域都有豐富實踐經驗。

各大技術社群頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。

負責:

  • 中央/分銷預訂系統效能最佳化
  • 活動&券等營銷中臺建設
  • 交易平臺及資料中臺等架構和開發設計
  • 車聯網核心平臺-物聯網連線平臺、大資料平臺架構設計及最佳化
  • LLM Agent應用開發
  • 區塊鏈應用開發
  • 大資料開發挖掘經驗
  • 推薦系統專案

目前主攻市級軟體專案設計、構建服務全社會的應用系統。

參考:

  • 程式設計嚴選網

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章