在領域驅動設計(Domain-Driven Design, DDD)中,我們常常將「戰略設計」與「戰術設計」並列思考。戰略設計幫助我們界定邊界、拆分業務範疇與微服務的界線;而戰術設計則進一步深入到具體的程式設計與架構實踐,讓領域模型能夠落實到程式碼之中。本文將從 Model-Driven Design 的核心理念出發,逐一介紹戰術設計中的重要構件與設計模式,並說明它們如何支撐我們打造高內聚、低耦合、具備演進性的微服務系統。
戰術設計最重要的基石,是 Model-Driven Design(模型驅動設計)。這是一種以《領域模型》為核心的設計方法論,它強調軟體設計必須從業務出發,並透過不斷演進的模型,連結業務專家與技術人員,最終形成既符合業務需求、又具備技術可行性的系統。
統一語言其實就是團隊之間在尋求「共識」的一種過程。
Most developers have never seen a domain model. They've only seen data models.
在 2017 年歐洲的 DDD 年會中,Cyrille Martraire 提到大部分的開發人員並沒有看過「領域模型」,經過我自己的經驗調查看起來好像也是這樣。
Doamin Model 是一群「名詞」的連結!
Entity 是戰術設計中最直觀的建構。它的核心特徵是 具備唯一識別(Identity),並且隨著時間演進,內部狀態可能會發生變化。
實體設計的挑戰:過度依賴資料庫 ID,而忽略了業務層面的識別。DDD 強調的是 業務身份,而非技術層面的自增主鍵。 (放下 DB 立地成 ....)
Value Object 是用來表達一個概念的值或特性,沒有唯一身份,而是由其屬性決定。
反模式提醒:如果值物件僅剩下資料而沒有行為,就會淪為所謂的「貧血模型」。這會破壞 DDD 的核心精神。 (我們經常看到人們寫一個類別,然後只有 Getter and Setter 沒有核心業務邏輯)
Aggregate 是一種更高層次的建構,用來管理相關實體和值物件的整體。
Service 負責封裝那些不屬於任何單一實體或值物件的業務邏輯。
最佳實踐:Service 不應該淪為「大雜燴」,而應保持高內聚,僅承擔必要的協調角色。
Factory 模式負責複雜物件的創建,將初始化邏輯與業務使用分離。
Repository 是領域層與資料持久化之間的抽象橋樑。
好處:讓領域模型專注於業務邏輯,而非資料存取。
特性:
過去式命名(如 OrderShipped、PaymentCompleted)。
具備業務意義。
案例:
當訂單完成付款後,系統會觸發 PaymentCompleted 事件,其他子系統(例如物流或通知系統)可以訂閱並執行後續處理。
價值:
領域事件能夠 解耦 Bounded Context 之間的通訊。
在微服務架構中,領域事件更能支撐獨立部署與高擴展性。
典型的 DDD 分層架構包含:
價值:透過分層,我們能讓領域邏輯與外部技術細節解耦,提升系統的可維護性。
戰略設計幫助我們劃分 Bounded Context,而戰術設計則是將這些界線具體落實到程式碼中。二者的關聯可以歸納為:
• 戰略設計決定邊界:哪些功能屬於哪個服務。
• 戰術設計落實細節:如何在該服務內部以 Entity、Value Object、Aggregate 等方式實現。
• 領域事件:成為不同微服務之間的溝通橋樑。
這也是為什麼 DDD 成為微服務設計的主要方法論之一。
戰術設計是 DDD 的落地實踐,透過 Entity、Value Object、Aggregate、Service、Factory、Repository、Domain Events 與分層架構,我們能將抽象的業務需求轉化為具體的程式結構。更重要的是,這些模式讓系統具備高內聚、低耦合、持續演進的能力,支撐微服務的長期發展。
在今天快速變動的數位環境中,業務需求不斷演進。唯有透過 DDD 戰術設計,我們才能打造真正與業務緊密貼合的軟體,並且在技術上保持彈性與可持續性。這正是 DDD 能在微服務浪潮中成為核心方法論的原因。