🎯 什麼情境該想到我
分工:這張是三選一的快速判準。三個建構區塊各自的完整展開——判準、Go 的實作方式、常見錯誤、兄弟辨析 → 實體、值物件(DDD)、聚合。
當你在設計領域模型的結構,猶豫「這東西該有身分嗎、一致性邊界該畫在哪」時。
⚙️ 怎麼用(三個建構區塊)
- Entity(實體):有唯一身分、生命週期中即使屬性變了仍是「同一個」(如:一個訂單)。
- Value Object(值物件):沒有身分,只看值是否相等、不可變(如:金額、地址)。優先用值物件,簡單又安全。
- Aggregate(聚合):一組相關物件的一致性邊界,有一個 Aggregate Root 當唯一入口;外部只能透過 root 改動內部,交易一次只改一個聚合。
★ 30 秒判斷流程
這個東西需要被「追蹤」嗎?(屬性全變了,它還是「同一個」嗎?)
├─ 否 → 值物件(金額、地址、日期區間、座標)
│ → 不可變、用值比較、自帶驗證
└─ 是 → 實體(訂單、使用者、帳戶)
→ 它和哪些東西必須「同時」保持一致?
├─ 有一條規則同時涉及它和其他物件 → 把它們放在同一個聚合,選一個當根
└─ 沒有 → 它自己就是一個聚合(最常見的情況)
★ 最常見的三個誤判
| 誤判 | 症狀 | 改法 |
|---|---|---|
| 所有東西都做成實體 | 到處是 ID 欄位、Address 也有自己的資料表和 ID | 問「它被單獨追蹤嗎?」——地址通常不是 |
| 聚合畫太大 | 一個 Customer 聚合包含所有訂單;每次下單都要鎖整個客戶 | 從真正的不變式反推邊界;訂單自己是一個聚合,用客戶 ID 參照 |
| 在一個交易裡改兩個聚合 | 下單同時扣庫存,兩個聚合在同一個交易裡 | 一個交易只改一個聚合;其他用領域事件達成最終一致 |
「從不變式反推邊界」的完整方法、跨聚合一致性三種做法的代價 → 聚合。
🧪 我實際套用的紀錄
- 2026-07-14:(待填)
⚠️ 注意
- 聚合別設太大(一致性成本高);一次交易一個聚合,跨聚合用最終一致性(見 工具-Transactional-Outbox-Pattern)。