Skip to main content

領域驅動設計 (DDD) 精華整理

DDD 不是資料夾改名或套用技術模板(如 UserService),而是一套設計哲學:讓軟體架構精準反映業務邏輯,並讓開發者與業務專家使用同一套語言。

一、核心觀念:軟體即業務的鏡像

  • DDD 是方法,不是技術規範——用來讓開發者與業務專家(Domain Experts)達成共識。
  • 關鍵目標: 程式碼反映業務領域,且團隊與業務使用同一套語言
  • 常見誤區: 把 DDD 當成「資料夾結構」「微服務專用」或「萬靈丹」。

二、兩大組成:戰略 vs 戰術

多數團隊只做「戰術」,卻忽略更重要的「戰略」。

戰略設計 (Strategic Design) —— 大局觀

決定系統邊界與架構,是最關鍵的一步。

概念說明
界限上下文 (Bounded Contexts)定義模型邊界。同一詞(如「客戶」)在銷售與售後系統中意義不同,應拆成不同上下文。
上下文地圖 (Context Maps)描述各邊界之間如何溝通與協作。

戰術設計 (Tactical Design) —— 實作細節

程式碼層級的模式,用來具體建立模型。

模式說明
實體 (Entities)有唯一 ID 的物件(如:訂單)。
值物件 (Value Objects)由屬性定義、不可變、無 ID(如:金額、地址)。
聚合 (Aggregates)一組相關物件,由「聚合根」控制存取,確保資料一致性。
領域事件 (Domain Events)描述已發生的事實(如:OrderPlaced),用來解耦不同上下文。

三、共通語言 (Ubiquitous Language)

共通語言是 DDD 的靈魂。

  • 定義: 開發、PM、QA 與業務專家在溝通與程式碼中,使用完全相同的詞彙
  • 對比:
    • 非 DDD:processRecord(status = 1) —— 業務聽不懂。
    • DDD:approveLoanApplication() —— 業務與程式碼一致。

四、常見四大錯誤

  1. 貧血領域模型 (Anemic Domain Models)
    實體只有 Getter/Setter,邏輯全塞在 Service,違反物件導向與 DDD。

  2. 單一萬能模型 (One Model to Rule Them All)
    用一個「客戶」類別滿足全公司需求,導致物件臃腫難維護。

  3. 直接跳入戰術模式
    邊界還沒釐清,就開始爭論「是實體還是值物件」。

  4. 忽視共通語言
    程式碼名詞與業務名詞脫鉤,增加翻譯與溝通成本。

五、實踐路徑建議

  1. 先學語言: 建立術語表,讓程式碼與業務專家說同一套話。
  2. 鎖定一個界限上下文: 從核心業務(最有價值的商業邏輯)開始。
  3. 紙上模擬:Event Storming(事件風暴) 工作坊,以便利貼對齊業務流程。
  4. 保持聚合精簡: 聚合越小,越容易維護與擴充。

總結

DDD = 正確的邊界 (Strategic) + 統一的語言 (Language) + 豐富的模型 (Tactical)

它是一場「理解業務」的長期修煉,而不是一次性的技術套用。