DDD術語-通用語言、限界上下文


在 DDD 領域建模和系統建設過程中,有很多的參與者,包括領域專家、產品經理、項目經理、架構師、開發經理和測試經理等。對同樣的領域知識,不同的參與角色可能會有不同的理解,那大家交流起來就會有障礙,怎么辦呢?在 DDD 中就出現了“通用語言”和“限界上下文”這兩個重要的概念。

什么是通用語言?

在事件風暴過程中,通過團隊交流達成共識的,能夠簡單、清晰、准確描述業務涵義和規則的語言就是通用語言。也就是說,通用語言是團隊統一的語言,不管你在團隊中承擔什么角色,在同一個領域的軟件生命周期里都使用統一的語言進行交流。

通用語言包含術語和用例場景,並且能夠直接反映在代碼中。通用語言中的名詞可以給領域對象命名,如商品、訂單等,對應實體對象;而動詞則表示一個動作或事件,如商品已下單、訂單已付款等,對應領域事件或者命令。

通用語言貫穿 DDD 的整個設計過程。作為項目團隊溝通和協商形成的統一語言,基於它,你就能夠開發出可讀性更好的代碼,將業務需求准確轉化為代碼設計。

下面這張圖描述了從事件風暴建立通用語言到領域對象設計和代碼落地的完整過程。

 

 

在事件風暴的過程中,領域專家會和設計、開發人員一起建立領域模型,在領域建模的過程中會形成通用的業務術語和用戶故事。事件風暴也是一個項目團隊統一語言的過程。

通過用戶故事分析會形成一個個的領域對象,這些領域對象對應領域模型的業務對象,每一個業務對象和領域對象都有通用的名詞術語,並且一一映射。

微服務代碼模型來源於領域模型,每個代碼模型的代碼對象跟領域對象一一對應。

這里我再給你分享一條經驗,我自己經常用,特別有效。設計過程中我們可以用一些表格,來記錄事件風暴和微服務設計過程中產生的領域對象及其屬性。比如,領域對象在 DDD 分層架構中的位置、屬性、依賴關系以及與代碼模型對象的映射關系等。

下面是一個微服務設計實例的部分數據,表格中的這些名詞術語就是項目團隊在事件風暴過程中達成一致、可用於團隊內部交流的通用語言。在這個表格里面我們可以看到,DDD 分析過程中所有的領域對象以及它們的屬性都被記錄下來了,除了 DDD 的領域對象,我們還記錄了在微服務設計過程中領域對象所對應的代碼對象,並將它們一一映射。

 

 

DDD 分析和設計過程中的每一個環節都需要保證限界上下文內術語的統一,在代碼模型設計的時侯就要建立領域對象和代碼對象的一一映射,從而保證業務模型和代碼模型的一致,實現業務語言與代碼語言的統一。

什么是限界上下文?

我們知道語言都有它的語義環境,同樣,通用語言也有它的上下文環境。為了避免同樣的概念或語義在不同的上下文環境中產生歧義,DDD 在戰略設計上提出了“限界上下文”這個概念,用來確定語義所在的領域邊界。

我們可以將限界上下文拆解為兩個詞:限界和上下文。限界就是領域的邊界,而上下文則是語義環境。通過領域的限界上下文,我們就可以在統一的領域邊界內用統一的語言進行交流。

綜合一下,我認為限界上下文的定義就是:用來封裝通用語言和領域對象,提供上下文環境,保證在領域之內的一些術語、業務相關對象等(通用語言)有一個確切的含義,沒有二義性。這個邊界定義了模型的適用范圍,使團隊所有成員能夠明確地知道什么應該在模型中實現,什么不應該在模型中實現。

我們可以通過一些例子進一步理解一下這個概念。

都說中文這門語言非常豐富,在不同的時空和背景下,同樣的一句話會有不同的涵義。有一個例子你應該聽說過。

在一個明媚的早晨,孩子起床問媽媽:“今天應該穿幾件衣服呀?”媽媽回答:“能穿多少就穿多少!”

那到底是穿多還是穿少呢?

如果沒有具體的語義環境,還真不太好理解。但是,如果你已經知道了這句話的語義環境,比如是寒冬臘月或者是炎炎夏日,那理解這句話的涵義就會很容易了。所以語言離不開它的語義環境。

而業務的通用語言就有它的業務邊界,我們不大可能用一個簡單的術語沒有歧義地去描述一個復雜的業務領域。限界上下文就是用來細分領域,從而定義通用語言所在的邊界。

正如電商領域的商品一樣,商品在不同的階段有不同的術語,在銷售階段是商品,而在運輸階段則變成了貨物。同樣的一個東西,由於業務領域的不同,賦予了這些術語不同的涵義和職責邊界,這個邊界就可能會成為未來微服務設計的邊界。看到這,我想你應該非常清楚了,領域邊界就是通過限界上下文來定義的。

限界上下文和微服務的關系

我想你買過車險吧,或者聽過吧。車險承保的流程包含了投保、繳費、出單等幾個主要流程。如果出險了還會有報案、查勘、定損、理算等理賠流程。

保險領域還是很復雜的,在這里我用一個簡化的保險模型來說明下限界上下文和微服務的關系。

 

 

首先,領域可以拆分為多個子領域。一個領域相當於一個問題域,領域拆分為子域的過程就是大問題拆分為小問題的過程。在這個圖里面保險領域被拆分為:投保、支付、保單管理和理賠四個子域。

子域還可根據需要進一步拆分為子子域,比如,支付子域可繼續拆分為收款和付款子子域。拆到一定程度后,有些子子域的領域邊界就可能變成限界上下文的邊界了。

子域可能會包含多個限界上下文,如理賠子域就包括報案、查勘和定損等多個限界上下文(限界上下文與理賠的子子域領域邊界重合)。也有可能子域本身的邊界就是限界上下文邊界,如投保子域。

每個領域模型都有它對應的限界上下文,團隊在限界上下文內用通用語言交流。領域內所有限界上下文的領域模型構成整個領域的領域模型。

理論上限界上下文就是微服務的邊界。我們將限界上下文內的領域模型映射到微服務,就完成了從問題域到軟件的解決方案。

可以說,限界上下文是微服務設計和拆分的主要依據。在領域模型中,如果不考慮技術異構、團隊溝通等其它外部因素,一個限界上下文理論上就可以設計為一個微服務。

總結

通用語言確定了項目團隊內部交流的統一語言,而這個語言所在的語義環境則是由限界上下文來限定的,以確保語義的唯一性。這兩者相輔相成,通用語言定義上下文含義,限界上下文則定義領域邊界,以確保每個上下文含義在它特定的邊界內都具有唯一的含義,領域模型則存在於這個邊界之內。

領域專家、架構師和開發人員的主要工作就是通過事件風暴來划分限界上下文。限界上下文確定了微服務的設計和拆分方向,是微服務設計和拆分的主要依據。如果不考慮技術異構、團隊溝通等其它外部因素,一個限界上下文理論上就可以設計為一個微服務。

限界上下文在微服務設計中具有很重要的意義,如果限界上下文的方向偏離,那微服務的設計結果也就可想而知了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM