停止教條式的領域驅動設計 - CodeOpinion

banq發表於2021-06-11

領域驅動設計的主流思想是關於實體、值物件、聚合、儲存庫、服務、工廠……各種技術模式。因此,大多數人認為他們不需要領域驅動設計,因為這對他們的領域來說很複雜。
為什麼你需要所有這些“東西”?好吧,也許你不需要!
在一個大型系統中,如果您正確使用儲存庫模式,建模您的領域、定義邊界以及它們之間的關係遠比關心您自己重要得多。
 
邊界對我來說可能是領域驅動設計中最重要的方面。但是,您將在網上找到的關於 DDD 的絕大多數內容或討論都圍繞著戰術模式:實體、值物件、儲存庫、服務、聚合等。雖然戰術模式具有價值,但它們必須在理解使用有界上下文定義邊界的概念和價值之後出現。雖然有界上下文確實得到了領域驅動設計愛好者的很多關注,但它並不是人們在教程或“示例”應用程式中首先被介紹的內容。
 

以下是我看到的與領域驅動設計最相關的一些評論和問題:

  • DDD 僅在您的業務邏輯複雜時才強大

雖然我同意複雜性是一個驅動因素,但我也認為在處理更大的系統時它對我幫助最大。來自領域的複雜性以及來自大型系統的複雜性。
  • 在 DDD 中,您應該使用儲存庫模式。

您需要使用工廠來建立實體或值物件。
  • 您的實體中沒有邏輯,因此這是一個貧血的域模型,這是一種反模式。

如果您認為自己已經有了領域模型,但實際上擁有包含事務指令碼的資料模型,那麼這只是一種反模式。隨著您對問題的理解不斷髮展,從這一點開始並轉向更豐富的領域模型並沒有任何問題。
  • 領域模型中不能有依賴項

人們不遺餘力地避免在他們的領域模型中存在依賴關係。雖然再次避免依賴是一個很好的做法並且值得努力,但有時您實際上需要依賴。使用Double Dispatch還不錯,因為您將依賴項傳遞給方法,並且有人告訴您所有依賴項都必須透過建構函式注入。
 

教條領域驅動設計
我認為上述所有問題都忽略了領域驅動設計的好處。只關心戰術模式是一種教條的DDD
對我來說,領域驅動設計是關於理解你的領域、語言、其中不同人的背景上下文( 上下文為王 )、問題和解決方案空間,並嘗試對其進行建模。而且一開始你不會做對,因為在你獲得的洞察力的基礎上迭代構建需要時間。
像聚合這樣的戰術模式(這是一個一致性邊界)是有價值的但這不應該是重點。僅僅因為你有儲存庫、聚合、實體,並不意味著你在做領域驅動設計。你只有一堆模式。
 

統一語言與術語
我發現語言是理解邊界和定義系統內有界上下文的好方法。一個很好的例子來自康威定理的Mel Conway。

當一個政客用“你好嗎?”和一個護士用“你好嗎?”來問候你時,他們是完全不同的問題,儘管他們的發音和拼寫都是一樣的。

這說明機器翻譯有什麼意義?


根據您在域中與誰交談,根據他們所在的子域或他們所扮演的角色,他們可能有不同的上下文。
正如 Mel 所指出的那樣,上下文對語言和意圖的使用方式很重要。
例如,在運輸貨物/貨物的運輸公司中,有多個子域。招聘是招聘司機,確保他們擁有適當的執照、合規性等。運營部門關注實際發貨以及取貨和交付的貨物。
兩者都有車輛的概念。但兩者對車輛是什麼都有非常不同的關注和觀點。他們使用相同的術語“車輛”,但根據他們的上下文,對對我來說重要的事情有非常不同的看法。
在招聘中,車輛的概念可能由駕駛員(稱為所有者操作員)擁有。他們可能關心車輛安全要求和其他合規性。運營部門關心車輛的可用性以及它是否可以在給定時間進行特定的運輸。非常不同的擔憂。
 

領域發現
起初,您沒有房間實際外觀的心理模型。當你慢慢地在房間裡閃爍燈光時,你會得到一個更好的關於天花板有多高、房間的形狀、地板上有什麼的心理模型。當你發光時,你的理解會慢慢增長。
理解域的邊界需要付出努力,並且是能夠理解問題和解決方案空間的關鍵。這是領域建模的關鍵。
 

領域驅動設計
標題說明了一切。這不是模式驅動設計,而是領域驅動設計。不要陷入專注於戰術模式的教條多數派。再次,是的,它們很有價值。聚合設計是定義一致性邊界的好方法。我不是在貶低模式,但這不是重點。模式是達到目的的手段。



 

相關文章