Skip to content

領域驅動設計 Domain-Driven Design(DDD)

Intro

接觸程式開發數年,碰到過幾次不只是需要把程式碼寫出來能跑能走就可以的情況,而是必須先規劃好一個系統的藍圖,開發則是最後的部分。在思維方面,除了基本的 MVC 架構,還可以再往上探討何謂領域驅動設計。

為什麼需要學習領域驅動設計?

你想要心流被打斷嗎?

身為程式開發者,平時最常做的就是把規格變成程式碼,這段變魔法的時光最令人流連忘返,往往一進入心流就不想離開,只想一直沉浸在打 code 中。

無奈需求者或業務常常會打破你的美好心流時光。最常出現的原因就是--你的程式出 bug 了!

為了減少 bug 打斷我們的美好 coding 時光,開發者在寫單元測試上下足了工夫,讓程式碼保證能運作。

但你有沒有想過,或許一條一條的規格之間,其實存在著一時無法發現的矛盾?尤其當專案愈大愈難以掌控所有細節之間的互相影響程度,直到使用者用奇葩的方式操作你的系統,產生一堆根本想像不到也測試不到的問題,業務才又回頭來煩你。

為了減少這種困擾,也確保業務能在專案啟動前就先釐清好規格,我們需要一種共同的語言來討論整個系統要解決的核心問題,那就是--領域驅動設計。

聽起來很複雜,真的能搞懂嗎?

其實程式開發者在不知不覺中已經接觸過相關的概念,甚至不自覺地應用在每一個專案架構上。

問問自己下面幾個問題:

  • 我會用 MVC 來架構專案嗎?
  • Controller 不應該寫邏輯,邏輯應該放在 service 內?
  • 我會在 controller 中調用 service,在 service 透過 model 建立實體,操作其本身提供的方法嗎?
  • 使用者應該叫做 user、權限驗證相關的命名應該叫 auth、

其實你已經在實踐領域驅動設計,只不過沒有領域專家。

什麼是領域驅動設計(DDD)

在開始了解 DDD 之前,先來定義一下何謂領域(Domain)。

什麼是 Domain?

Domain(knowledge),是指「一塊知識的範圍」,實務上就是指「工作上所需的知識集合」,包含「問題」及「解決方案」。

引用自 關於 Domain-Driven Design 以及他的魅力

「業務知識」驅動設計

也就是說,DDD 其實就是圍繞在「要解決的問題點」的系統設計。

根據 維基百科,領域驅動設計 Domain-Driven Design(DDD) 軟體程式碼中的結構及語言(類別、方法、變數命名)需要符合業務領域中的習慣用法。

領域驅動設計的核心

  • 把專案的重點與邏輯放在核心領域(core domain)
  • 以領域中的模型為基礎進行設計
  • 技術人員需與領域專家合作,以迭代方式完善特定領域問題的概念模型

概念與層級

概念定義
上下文(Context)情境、脈絡、上下文,例如:電子商務系統
限界上下文(Bounded Context)定義特定模型的適用範圍
領域(Domain)特定業務領域的知識與流程,是軟體要解決的問題空間
通用語言(Ubiquitous Language)讓領域專家與開發團隊在同一溝通平面上,為了描述領域模型而建構的語言
模型(Model)將概念系統化的抽象類
實體(Entity)有唯一標識的對象,身份在整個生命週期中保持不變
領域服務(Domain Service)封裝領域邏輯
層級定義
用戶介面層(Presentation Layer)能與使用者(人或其他服務)互動的接口
應用層(Application Layer)領域及介面之間的橋樑,將接口的操作拆解並調用業務邏輯組裝
領域層(Domain Layer)只關心領域業務邏輯,不關心用戶如何操作
基礎設施層(Infrastructure Layer)確保系統穩定順暢運行的相關作業

下一步該怎麼走?

DDD 需要管理人員的把關,才能集合多方人員共同參與。

以我的狀況而言,目前接觸到的案例都還沒有專注在 DDD 的情況,因此只能先做筆記,還無法知道應用起來會是怎樣的情況。不過接觸到的系統中出現滿多 DDD 的影子,參考其他開發者的想法與設計,也能提升自我設計能力,至少在沒有領域專家的情況下,能夠規劃一些常見的通用架構吧。


參考資料