領域驅動設計 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),是指「一塊知識的範圍」,實務上就是指「工作上所需的知識集合」,包含「問題」及「解決方案」。
「業務知識」驅動設計
也就是說,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 的影子,參考其他開發者的想法與設計,也能提升自我設計能力,至少在沒有領域專家的情況下,能夠規劃一些常見的通用架構吧。