領域驅(qū)動設計入門
領域驅(qū)動設計(DDD)是由Eric Evans發(fā)明的一個概念。他在2004年出版的《領域驅(qū)動設計》一書(即”大藍皮書“)中探討了這個概念。
那么在DDD上下文中,領域是什么?
領域是知識、影響或活動的范圍。用戶應用程序的主題域即軟件的領域。
我將概要地介紹下DDD的方方面面。本文將探討DDD“為什么?”和“是什么?”。在這里,我不會深入探討具體的主題。不過,我會說明重要術語的定義,就像上面的“領域”。你會發(fā)現(xiàn),共享詞匯也是DDD本身的一部分。
首先,你要問自己,這些概念是否仍然有效?
DDD不是一種特定的技術,它是一個概念。許多現(xiàn)代概念都直接使用DDD。下面這段話出自Sam Newman《微服務設計》一書的第一頁。
Eric Evans的《領域驅(qū)動設計》一書幫助我們理解了用代碼呈現(xiàn)真實世界的重要性,并且告訴我們?nèi)绾胃玫剡M行系統(tǒng)建模。
此外,IBM Garage事件驅(qū)動參考架構有一章專門介紹DDD方法。
至于DDD的意義,可以說時至今日,它確實非常有效。說完了最新的情況,讓我們繼續(xù)探討 “為什么?”和 ”是什么?“
DDD不是一種特定的技術,它是一個概念。許多現(xiàn)代概念都直接使用DDD。下面這段話出自Sam Newman《微服務設計》一書的第一頁。
為什么會需要像DDD這樣的東西?Eric Evans在其著作的副標題中提供了一條很好的線索:
攻克軟件核心的復雜性
通常情況下,軟件項目的主要復雜性在于領域本身。你無法改變領域的復雜性。你可以試試告訴你的銀行客戶,你將專注于支付,而放棄貸款業(yè)務,因為它太復雜了。
此外,我們不是為了開發(fā)軟件而開發(fā)軟件。我們是為了解決問題以及做些改進:
軟件的核心是為用戶解決領域相關問題的能力。其他所有功能,雖然也很重要,但都是服務于這一基本目的。
微服務的關鍵特征之一就是其松散的耦合,而這一特征則允許它們單獨進行開發(fā)、部署、訪問控制和擴展。
那么DDD是什么?DDD無法用一兩個句子定義。它是一種開發(fā)解決多個問題的復雜軟件的方法:
關注領域的核心復雜性和機會;
領域?qū)<液蛙浖<液献魈剿?/span>模型;
在有界上下文中說一種通用語言。
(注意正文中的綠色詞匯。這些是DDD中特有的術語,我會給它們下個定義,就像給領域下定義一樣。)
這三點是對DDD非常高度的概括。接下來,我會一個一個地介紹。
這一點我就不過多介紹了。根本的東西我在上面“為什么”這一部分里都已經(jīng)說明了。軟件是沒有自我目的的。
不要把這點和“關注業(yè)務”弄混了。核心復雜性和機會與我們所說的“業(yè)務”并不是一回事。想一下Twitter。在它的功能中,互相關注等功能并非主要的復雜性所在。主要的復雜性更多的可能還是來自擴展平臺。
領域?qū)<液蛙浖<液献魈骄磕P汀?/span>
模型是應對上述復雜性的一種方法。但首先,我們要弄清楚模型是什么?
在DDD上下文中,模型是什么?
描述領域部分方面的一系列抽象,可以用于解決與該領域相關的問題。
另一種來自Eric Evans的描述:
模型是一種簡化。它是對現(xiàn)實的解釋,它將有助于解決現(xiàn)有問題的重要方面抽象出來,而忽略掉不相干的細節(jié)。
我覺得有必要明確下它不是什么:它不是一張圖(因此也不是實體關系圖(ERD),雖然DDD也使用實體這個術語)。圖只是幫我們就模型進行交流。在DDD的語境下,你會看到許多圖。沒有什么唯一的建模專用語言。最常用的是一些類似UML的圖,或者僅僅是一幅手繪草圖。重要的不是圖,而是圖背后的概念。
選擇“探索(explore)”而不是像“寫下”這樣的詞,是有其用意的。要獲得一個模型,需要經(jīng)過一個迭代過程。建模這樣的事不可能一次性完成。領域里會有新的洞察,新的或變化的問題,諸如此類。這是一個持續(xù)探索的過程。
模型舉例
考慮下平常的世界地圖(有點像一張圖)。標準世界地圖顯示的是墨卡托投影。人們都知道,地圖不是為了說明不同國家的大小或其他類似的東西。它是專門為海上航行而制作的。在地圖上的兩點之間畫一條線,借助指南針就可以知道如何航行了。
下圖顯示了地圖背后的東西,即具體的模型:

Eric Evans在2019年的會議演講中使用的這個例子很不錯。它說明了模型與當前的問題直接相關。
有個模型并不能讓你獲得任何優(yōu)勢。優(yōu)勢并非因為有模型。優(yōu)勢是你因為有一個模型,可以非常好的匹配你正在設法解決的一組特定問題。
對比開頭的句子,這里少了一個非常重要的部分:“領域?qū)<液蛙浖<液献鳌啊?/span>模型必須合作探索。不是單由領域?qū)<覄?chuàng)建模型,也不是單由開發(fā)人員拿ERD當模型叫賣。Eric Evans將合作探索模型的過程稱為“知識研磨(Knowledge Crunching)”。
在本節(jié)的最后,讓我們看一個非常重要的觀點。Eric Evans的下面兩段話是這一觀點的最佳表述。
本書的主旨是,實施、設計和團隊溝通應該在一個模型里。不同的用途采用不同的模型會存在隱患。
如果編寫代碼的人覺得自己不負責模型,或者不理解如何在應用程序開發(fā)中運用模型,那么模型就和軟件沒關系了。如果開發(fā)人員沒有意識到修改代碼會改變模型,那么他們的重構會弱化而非強化模型。
本節(jié)要點:代碼和模型直接相關。
上面的內(nèi)容是對DDD一個高度概括的介紹。無疑,它還有許多其他的概念。

上圖是DDD中不同概念的一個總覽。如你所見,我只介紹了其中的一小部分。我接下來會寫一篇文章介紹實體、值對象和聚合的概念。但本文足以幫你了解DDD是干什么的。
DDD仍然是你工具箱中的一個重要概念。它已經(jīng)影響了許多其他的領域可以看下JPA規(guī)范的JavaDoc:https://github.com/spring-projects/spring-data-jpa/blob/main/src/main/java/org/springframework/data/jpa/domain/Specification.java
并且還會繼續(xù)影響它們。
解決領域問題是軟件開發(fā)的全部內(nèi)容。那是我們需要面對的復雜性。但是,運用DDD可以讓我們的工作變得更輕松。
希望您喜歡這篇文章。歡迎反饋。您可以在Twitter或LinkedIn上聯(lián)系我:https://twitter.com/JannikWempehttps://www.linkedin.com/in/jannik-wempe/
相關資料
當然,最主要的資料是《領域驅(qū)動設計》一書:https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/
Eric Evans在網(wǎng)上免費提供的領域設計驅(qū)動參考:https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf。
IBM Garage事件驅(qū)動參考架構也包含有關DDD的信息:https://ibm-cloud-architecture.github.io/refarch-eda/methodology/domain-driven-design
我很喜歡Eric Evans在DDD歐洲2019大會上的這個演講:https://youtu.be/pMuiVlnGqjk
當然,YouTube上還有其他許多不錯的演講。
