DDD 戰略設計#
模組化與依賴方向告訴我們「怎麼切」才內聚低耦合,但沒回答一個更前置的問題:該沿著哪條線切? 領域驅動設計(Domain-Driven Design, DDD)的**戰略設計(Strategic Design)**提供了答案——以業務領域的自然邊界作為切分依據。本章只談戰略層(宏觀邊界劃分),不涉及實體、值物件等戰術層細節。
本章開宗明義先講清楚:DDD ≠ 微服務。DDD 是一套劃分業務邊界的方法論,產出的是「限界上下文」這種邏輯邊界;要不要把每個上下文部署成一個獨立微服務,是另一個(架構風格層級的)決策。DDD 在單體裡同樣適用。微服務拆分如何借用這些邊界,見服務拆分策略。
統一語言(Ubiquitous Language)#
戰略設計的地基,是統一語言:開發者、領域專家、產品在「同一個邊界內」使用完全一致的術語,且這套術語直接體現在程式碼裡(類別名、方法名)。
- 沒有「業務說 A、程式碼叫 B、文件寫 C」的翻譯損耗。
- 同一個詞在不同上下文可以有不同意義——這正是需要劃分邊界的訊號。
例如「商品(Product)」:在「商品目錄」上下文裡指規格、描述、分類;在「庫存」上下文裡指 SKU 與數量;在「物流」上下文裡指重量與體積。硬要全公司共用一個
Product巨型模型,反而把不相干的概念綁死。
限界上下文(Bounded Context)#
限界上下文是統一語言成立的邊界——在這個邊界內,每個術語都有單一、明確的意義;跨出邊界,同名術語可能意義不同。它是 DDD 最核心的戰略概念。
flowchart LR
subgraph BC1[商品目錄 Context]
P1[Product = 規格/描述/分類]
end
subgraph BC2[庫存 Context]
P2[Product = SKU/數量]
end
subgraph BC3[物流 Context]
P3[Product = 重量/體積]
end
style BC1 fill:#e3f2fd
style BC2 fill:#e8f5e9
style BC3 fill:#fff3e0限界上下文同時是模型邊界與團隊/所有權邊界:一個上下文有清楚的負責團隊,內部高度內聚,對外只透過明確契約溝通。它天然滿足第 9 章的高內聚低耦合。
子域分類:把精力放在對的地方#
業務領域(Domain)可拆成多個子域(Subdomain)。依「是否是公司競爭力來源」分三類,決定投資策略:
| 子域類型 | 定義 | 投資策略 | 例子(電商) |
|---|---|---|---|
| 核心子域(Core) | 公司賴以致勝的差異化能力 | 最強團隊自研,精雕細琢 | 推薦演算法、動態定價 |
| 支撐子域(Supporting) | 必要但無差異化,配合核心 | 自研但求堪用,或外包 | 商品評論、賣家後台 |
| 通用子域(Generic) | 業界通用、已有成熟方案 | 直接買 / 用現成(不要自研) | 金流、寄信、登入認證 |
子域分類最大的價值是指導取捨,呼應合適原則:把最好的人力與最複雜的架構留給核心子域;通用子域千萬別自己造輪子。判斷標準是「這塊做得比對手好,客戶會不會因此選我們?」——會,才是核心。
子域(業務的問題空間)與限界上下文(解決方案的邊界)理想上一一對應,但實務上可能多對多,需要刻意對齊。
Context Map:上下文之間的關係#
系統由多個限界上下文組成,它們必然要協作。Context Map(上下文映射)描繪這些上下文間的整合關係與權力結構——誰受誰影響、誰要遷就誰。
flowchart TD
Catalog[商品目錄] -->|共享核心| Search[搜尋]
Order[訂單] -->|客戶-供應商<br/>U/D| Payment[支付閘道]
Order -->|防腐層 ACL| Legacy[舊 ERP]
Promo[行銷活動] -->|遵奉者| Catalog
Risk[風控] -.各行其道.- Recommend[推薦]
style Order fill:#e3f2fd
style Legacy fill:#ffebee
style Payment fill:#fff3e0常見的關係模式:
| 關係模式 | 權力/方向 | 適用情境 |
|---|---|---|
| 共享核心(Shared Kernel) | 雙方共管一小塊共用模型 | 兩團隊緊密協作,願意共同維護一小段重疊 |
| 客戶-供應商(Customer-Supplier) | 上游(U)供應、下游(D)消費;下游有發言權 | 上游願意配合下游需求排優先序 |
| 遵奉者(Conformist) | 下游完全順從上游模型,無發言權 | 上游強勢(如大平台 API),下游只能接受 |
| 防腐層(ACL, Anti-Corruption Layer) | 下游建一層轉換,隔離上游模型 | 上游是爛模型/舊系統,不想讓它污染己方 |
| 開放主機服務(OHS)+ 發布語言(PL) | 上游提供標準化公開協定 | 上游要服務多個下游,定義通用整合協定 |
| 各行其道(Separate Ways) | 完全不整合 | 整合成本高於收益,乾脆切開 |
防腐層(ACL) 是實務上最常用、也最值得投資的模式:當你必須對接一個模型混亂的舊系統或第三方時,建一層轉換,把外部概念翻譯成自己上下文的統一語言。它正是第 9 章端口-適配器在領域整合層級的應用——保護核心模型不被外部細節腐蝕。
與微服務拆分的關係#
限界上下文與微服務常被混為一談,務必分清:
| 概念 | 本質 | 邊界類型 | 是否需獨立部署 |
|---|---|---|---|
| 限界上下文 | 領域模型的語言邊界 | 邏輯邊界 | 不一定 |
| 微服務 | 可獨立部署的執行單元 | 物理邊界 | 是 |
合理的關係是:限界上下文是微服務拆分的「候選邊界」。一個上下文可以:
不要「一個限界上下文一定要一個微服務」地教條化。先用 DDD 把邏輯邊界劃清楚(這在單體裡就該做),再依架構風格的取捨決定物理部署。把語言邊界劃錯,拆成再多微服務也是分散式大泥球。微服務的拆分時機與粒度,詳見服務拆分策略。
本章小結#
| 主題 | 核心觀點 |
|---|---|
| 統一語言 | 同一邊界內術語完全一致,並落到程式碼 |
| 限界上下文 | 統一語言成立的邊界,同時是模型與團隊邊界 |
| 子域分類 | 核心/支撐/通用,指導人力與自研/採購取捨 |
| Context Map | 描繪上下文間的整合與權力關係;ACL 最常用 |
| DDD ≠ 微服務 | 上下文是邏輯邊界、是微服務的候選;是否獨立部署另行決策 |