---
# System prepended metadata

title: What is Domain Driven Design (DDD)?
tags: [Architecture]

---

# What is Domain Driven Design (DDD)?

==破題==
> Domain Driven Design 是一種以「業務領域」為核心的軟體設計方法。
它透過與業務相關者建立「共通語言 (Ubiquitous Language)」，並在程式中建立貼合業務邏輯的領域模型，使系統可維護、可演進且不易走樣。

---
### 為什麼我們需要這個概念？

軟體的核心是為使用者解決業務需求，
隨著服務越來越多樣化、流程越來越複雜，系統不再只是資料庫的 CRUD，而是需要處理：
- 一連串業務規則
- 多種角色行為
- 不變條件（Invariants）
- 日益變動的需求

這些複雜性如果直接寫成 CRUD 風格的程式碼，系統很容易僵化、難以維護，也難以讓人從程式碼理解業務。
因此 Eric Evans 提出了 Domain-Driven Design（DDD），希望程式開發能夠更貼近業務邏輯，而不是只停留在資料表 CRUD。

下面用一段程式碼簡單演示差異：
> Service 後的實作不是重點，這裡就不展示該怎麼實作

```
// 沒有 ddd 概念的建立訂單（純 CRUD） 
var order = new OrderEntity {
    CustomerId = 1,
    Total = 500,
    CreatedAt = DateTime.UtcNow
};

var repo = new OrderRepo();
repo.Create(order);
```

```
// ddd 概念的建立訂單 (強調業務語意)
var orderRepo = new OrderRepo();
var orderService = new OrderService(orderRepo);

var orderId = orderService.CreateOrder(
    customerId: 1, 
    total: 500, 
    createdAt: DateTime.UtcNow);
```

上面兩段程式碼背後做的事情可能都只是 CRUD，
但語意完全不同：

> 上面只是「新增一筆資料」
> 下面是執行「建立訂單」這個業務行為

DDD 的目的不是讓程式碼變複雜，而是：
- 讓程式碼表達真正的業務邏輯
- 把規則封裝在領域模型中（不是散落在 Controller、Repository）
- 保護系統的業務邏輯（不變條件不會亂被破壞）
- 適應未來業務變化（加入新規則，不必大改架構）
- 讓開發團隊與業務人員使用同一語言

這能讓系統達到一種狀態：

>程式即設計，設計即程式（The code is the model）。

---
### 什麼是 DDD?
> Domain 就是 「為解決某個問題所需的全部知識集合」，包含問題本身、專業術語、業務規則與可行解法。
> ==DDD 就是以這個 Domain 為核心的軟體開發設計==



實作上 DDD 分為兩個層面
- 策略性 (Strategic): 與領域專家合作，將 Domain 劃分為各個 Subdomains，並明確界定 Bounded Contexts，把團隊的注意力放在能產生最大價值的 Core Subdomains 上
- 戰術性 (Tactical): 利用一系列的設計模式 (Aggregate, Entity, Repository ...etc) 實踐 Strategic Design 定義好的各個 Subdomain

白話來說，DDD 不只把方法命名的更語意化，更把 「業務邏輯、規則、共通語言」注入到 Model 中，使程式碼能直接表達業務


---
### 用共通語言 (Ubiquitous Language) 溝通

在 DDD 中，團隊必須建立一套「所有人都使用的語言」，包含業務、PM、工程師、QA、甚至程式碼本身。
這套語言用來描述：

- 業務流程
- 規則
- 模型
- 行為
- 邏輯

這麼做的目的，不只是減少溝通成本，而是：

>讓整個團隊在討論與開發時，都能指向同一個概念，沒有誤解與模糊地帶。

例如：「取消訂單」對技術人員可能以為只是把狀態改為 Cancelled；
但對業務來說，可能包含退款、回補庫存、通知顧客、更新發票等流程。

若沒有共通語言，系統最終會反映工程師「以為」的業務，而不是「真正」的業務。

![Screenshot 2025-11-27 at 5.33.39 PM](https://hackmd.io/_uploads/B1ybsqBWZx.png)
(Source: [fx777: 關於 Domain-Driven Design 以及他的魅力](https://ithelp.ithome.com.tw/m/articles/10216645))

---
### 配合業務邏輯，封裝 Method
看到這裡，讀者可能會以為：
>簡單來說，DDD 就是把方法封裝好嘛？

這句話有一半對，但遠不只如此。
DDD 的封裝不是一般的 OOP 封裝，而是：
只針對真正的業務行為進行封裝，並在 Model 中維護該行為的規則、不變條件與限制。

例如：

- Order.Cancel() 不是改一個欄位
- Order.Pay() 不只是「把 IsPaid 設為 true」
- Cart.AddItem() 要檢查庫存、檢查是否重複加入、計算金額等

這種封裝讓：

1. 程式模型與業務邏輯緊密綁在一起
2. 方法會隨著業務演進而演進
3. 方法名稱自然反映業務語意，不需要為命名苦惱

也就是說：

DDD 將業務語言、規則、流程直接放進程式碼，使模型本身就能表達業務。

---
### 優缺點
優點:
1. 統一專業術語（Ubiquitous Language）
讓跨角色（業務、PM、工程師）溝通一致，減少誤解。
2. 保護業務邏輯（封裝不變條件）
業務規則集中在 Model 中，不會被 Controller / Repository 分散污染。
3. 高度模組化，可測試性強
Aggregate、Value Object 都能獨立測試，維護成本降低。
4. 更容易拆分成 microservice
因為 bounded context 原本就界定了系統邊界，天然適合作為 microservice 切割基礎。

缺點:
1. 較難快速建立產品，前期需要大量討論 Domain
2. 要導入溝通文化、學習成本高
3. 沒有領域專家會很難開頭
若缺乏業務知識，Model 難以正確形成，也會讓 DDD 成為形式主義
4. 過度使用會成為負擔
如果 Domain 不複雜，硬套 DDD 會增加不必要的成本

#### 參考資料

[Jimmy Coding: 白话讲解领域驱动设计domain driven design (DDD)](https://www.bilibili.com/video/BV11u411176h/?spm_id_from=333.337.search-card.all.click&vd_source=8f375110dafd4e9c975e5276d51c4840)

[fx777: 關於 Domain-Driven Design 以及他的魅力](https://ithelp.ithome.com.tw/m/articles/10216645)

