iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 2
5

DDD 學習路徑與資源分享

cover

經過昨天的傳教文章,今天來為各位簡單介紹 DDD 學習路線以及這系列文章會涵蓋的範圍。
並在文末附上我評估對 DDD 感興趣的朋友有幫助的學習資源。

Learning Roadmap

DDD 主要分為兩大部分,分別為:

  • 戰略設計 Strategic Design :與領域專家探索完領域知識後,為了有效分析與實作,將領域拆分問題成數個子領域 Subdomain 並定義解決方案的邊界 Bounded Context 與關係 Context Map。
  • 戰術設計 Tactical Design :又稱 Model-Driven Design。利用 DDD 在戰術設計中提供的設計模式來實現戰略設計所分析的成果。

下張圖展示 DDD 模式的全貌:
img
圖 1. DDD 設計全貌圖
source: Domain-Driven Design Reference

Strategic Design 戰略設計

img

DDD 的戰略設計其目的在於協助我們捕捉和獲得領域知識Domain Knowledge,並且將其拆分成適當的大小以利後續分析處理,同時也讓我們能夠理解軟體的核心價值。戰略包括以下要點:

  • 團隊與領域專家溝通及合作捕捉領域知識並且建構通用語言Ubiquitous Language。
  • 依照所理解的問題域 Problem Space 以及解決方案域 Solution Space 的資訊建立領域 Domain。
  • 將領域 Domain 切成若干個子領域 Subdomain ,並定義每一個子領域的優先等級。
  • 在子領域中遵循通用語言將解決方案域切分出一個個語意的邊界:限界上下文 Bounded Context
  • 使用上下文地圖Context Mapping 模式定義不同限界上下文之間的互動模式 。

歷史小補充: 在 DDD 剛推出時,因為戰略部分非常抽象,所以很多人只學習可以立即導入程式碼中的戰術設計 又稱 DDDLite 模式。不過隨著程式碼逐漸增長,大家逐漸意識到沒有做好戰略設計,即使加入再多的戰術程式碼都是脆弱的。因為有了戰略打穩地基,團隊有了充足的領域知識與通用語言做後盾,才能準確設計系統的邊界以符合業務需求。

Tactical Design 戰術設計

戰術設計幫助我們運用一些成熟的 Design Pattern 將戰略分析的成果以程式碼實現。有以下 Design Pattern 供使用:

  • 實體 Entity
    能被識別出來的物件 有 id。 Entity 的狀態會在其生命週期中持續追蹤其變化。
  • 值物件 Value Object
    無 identity 概念、狀態不可變更的物件 object,用於描述某個事物的特徵。
  • 聚合 Aggregate
    由相關業務目標的物件 包含實體與值物件 所組成,一個聚合即為一個 Transaction 的邊界。並且會在其中選擇一個實體 作為聚合根 Aggregate Root ,所有與外界的溝通都必須交由聚合根來負責。

以上三個由於負責領域的業務邏輯,因此又被稱為領域物件 Domain Object。

  • 倉儲 Repository
    這是一個保存領域物件的狀態的設計模式,可以轉接資料庫、 ORM 或檔案系統。一般使用上會考慮一個聚合對上一個倉儲。
  • 工廠 Factory
    同 GoF 的工廠樣式,在 DDD 中用於處理聚合生成較為複雜的情境。
  • 領域事件 Domain Event
    某件領域專家在乎的事件,通常用於聚合間的溝通。
  • 領域服務 Domain Service
    當有某個業務邏輯職責無法被歸類到任何一個領域物件上時,會將以領域服務承載這個職責。處於應用服務與領域物件之間。
  • 應用服務 Application Service
    等同於系統的使用案例,主要負責技術細節並呼叫領域物件或領域服務處理業務邏輯。

如果以上看得霧煞煞,可以看以下這張精美簡版:

完整放大版點此連結

鐵人賽目錄

以上說了那麼多,以下會跟大家介紹本次鐵人賽會涵蓋到的部分。戰略部分會依照以下順序展開:

  • 領域,子領域,限界上下文 Domain & Sub Domain & Bounded Context
  • 上下文映射樣式 Context Mapping Patterns
  • 事件風暴 Event Storming

進入戰術設計前,我會先介紹一些現代的架構來支援戰術與戰略的實現以做到「關注點分離」:

  • 分層架構 Layered Architecture
  • 洋蔥/整潔架構 Onion/Clean Architecture
  • 接口-轉接器架構 Port-Adapter Architecture
  • 限界上下文整合 Bounded Context Integration

接著再進入大家期待的程式實作戰術設計:

  • 實體 Entity
  • 值物件 Value Object
  • 聚合 Aggregate
  • 工廠 Factory
  • 應用服務 Application Service (搭配 BDD 實踐)
  • 倉儲 Repository
  • 模組設計 Module
  • 領域服務 Domain Service
  • 領域事件 Domain Event
  • CQRS & Event Sourcing 不一定

最後有時間的話會找幾個簡單的 project 跟大家一起實作。

本系列風格說明

由於 DDD 大部分資源都以英文為主,且中文翻譯又容易有歧異,所以為了希望大家未來能無縫接軌英語資源,在專有名詞使用上,我都盡量以英文呈現 如 Bounded Context, Subdomain 等等 。因此會出現大量「晶晶體」也請多見諒。

本系列我主要是參考 [Implementing Domain-Driven Design]https://www.tenlong.com.tw/products/9787121224485 簡稱 IDDD 為主,此書實作內容非常豐富。不過不太建議新手直接拿來啃,最好是搭配本系列一起服用 XD

同時偶爾參考元祖書 Domain-Driven Design 與另一本好書 Patterns, Principles, and Practices of Domain-Driven Design 還有一堆網路文章與影片。

在程式語言實作方面,由於我熟悉的語言如 NodeJS 、 Python 等都不是純粹的物件導向語言,所以我就選用 TypeScript 主要程式語言來開發範例程式碼。如果你是用 JAVA 、 C# 、 PHP 等的朋友們...我只能說恭喜拉!網路上超多程式碼資源 尤其是 C#,可以從本系列理解概念後再上網找範例程式碼。

為了讓大家能快速上手 DDD 的概念,實踐方面我盡量都會寫出範例程式碼,但因為 30 天的極限挑戰下,若有錯誤也請各位不吝指出,我會立即修正,謝謝。

資源分享

有書籍、文章、影片與社群資源,非免費資源我會在後面標注星號。

書籍

文章

更多資源可以上 Awesome DDD 查看~

線上課程

最強社群

現在就加入 Domain-Driven Design Taiwan ,隨時更新活動與新知!
最近才剛辦完耗時半年的 Implementing Domain-Driven Design 的讀書會,如果對讀書會有興趣請密切關注!

也可以到 ddd-tw/ddd-events 翻翻過去活動留下來的資源。

最後感謝社群夥伴 Kim, Arther, Tim, James 為這篇提供許多精闢的建議。


上一篇
關於 Domain-Driven Design 以及他的魅力
下一篇
戰略設計:運用 Domain, Subdomain 與 Bounded Context 打造藍圖
系列文
Think in Domain-Driven Design30

尚未有邦友留言

立即登入留言