一文揭秘領(lǐng)域驅(qū)動設(shè)計(DDD):領(lǐng)域和子域!
來源:掘金
鏈接:https://juejin.cn/post/6898450822771539981
- 前言 -
眾所周知,領(lǐng)域驅(qū)動設(shè)計(DDD)是個相當(dāng)抽象的概念,國內(nèi)除了幾家知名大廠有成功實踐外,更多技術(shù)團隊還處于探索階段。想要以 DDD 思想指導(dǎo)架構(gòu)設(shè)計,我們首先需要對 DDD 所包含的概念有深入了解,今天,就和大家簡單聊聊 DDD 的核心概念:領(lǐng)域和子域。
- 領(lǐng)域和子域 -
在很長一段時間里,我們認(rèn)為技術(shù)是主導(dǎo)項目成功的關(guān)鍵因素,這種關(guān)鍵因素通常表現(xiàn)在項目使用的編程語言、框架、架構(gòu)(如:分層架構(gòu))、中間件、數(shù)據(jù)庫等等方面(如:生態(tài))。但技術(shù)真的是項目成功的關(guān)鍵因素嗎?
在一個軟件項目里除了技術(shù)層面的這部分,我們最主要的事情是實現(xiàn)業(yè)務(wù)。實現(xiàn)業(yè)務(wù)其實是在實現(xiàn)所在業(yè)務(wù)領(lǐng)域中所需要的業(yè)務(wù)。技術(shù)也是一個領(lǐng)域,稱之為技術(shù)領(lǐng)域。領(lǐng)域驅(qū)動設(shè)計中的領(lǐng)域是指的業(yè)務(wù)領(lǐng)域。
大多數(shù)的技術(shù)人員對技術(shù)領(lǐng)域中的知識比較感興趣(狂熱),因為這能夠使得自己在技術(shù)方面有一些前沿性和探索性的實踐。然而對于業(yè)務(wù)領(lǐng)域中的知識就顯得比較暗淡一些。
當(dāng)項目的進展隨著對業(yè)務(wù)領(lǐng)域的深入,大家又開始為各種曾經(jīng)沒有分析到的需求忙的焦頭爛額。這個時候?qū)夹g(shù)領(lǐng)域的探索也基本成熟。接著又一輪新技術(shù)的出現(xiàn),使得大家又開始對新技術(shù)進行探索實踐,并試圖使用新技術(shù)來解決掉以前遺留下來的沒有解決的新需求,此時就出現(xiàn)了所謂的“全盤重構(gòu)”。
正是這種周而復(fù)始的對技術(shù)領(lǐng)域的不斷探索,使我們對業(yè)務(wù)領(lǐng)域里重要的核心知識被埋沒。當(dāng)有一天我們認(rèn)識到業(yè)務(wù)領(lǐng)域十分重要時,你可能已經(jīng)不在這個業(yè)務(wù)領(lǐng)域中探索技術(shù)了。
讓一個技術(shù)水平較高的技術(shù)人員去深入研究分析領(lǐng)域中的業(yè)務(wù)是需要勇氣的,這種勇氣不是來自對未知的復(fù)雜業(yè)務(wù)領(lǐng)域的挑戰(zhàn)而是讓自己不在無時無刻沉靜在對技術(shù)探索的環(huán)境中。
這要求一些技術(shù)人員需要花費一些時間去深入到業(yè)務(wù)領(lǐng)域中去分析領(lǐng)域知識并最終形成領(lǐng)域模型。
問題:領(lǐng)域中的業(yè)務(wù)是由什么組成的呢?
回答:需求。
問題:需求又是有什么組成的呢?
- 什么是領(lǐng)域? -
百度百科對領(lǐng)域的解釋:
-
學(xué)術(shù)思想或社會活動的范圍。
-
具體指一種特定的范圍或區(qū)域。
在《領(lǐng)域驅(qū)動設(shè)計》中,領(lǐng)域指的是一個特定的業(yè)務(wù)范圍,大家在這個業(yè)務(wù)域范圍內(nèi)開展工作。
領(lǐng)域這個詞承載了太多的含義。在大多數(shù)人的理解中會使用領(lǐng)域代替行業(yè)、項目或者系統(tǒng),這樣會使一些人認(rèn)識領(lǐng)域就是行業(yè)、項目或者系統(tǒng)。在認(rèn)識領(lǐng)域時一定要注意所指的業(yè)務(wù)域,行業(yè)、項目或系統(tǒng)都不能準(zhǔn)確地表達領(lǐng)域所指的業(yè)務(wù)域。
-
一個系統(tǒng)可能由一個領(lǐng)域或者多個領(lǐng)域組成。如果一個系統(tǒng)是由一個領(lǐng)域組成時,這會給大家一種錯覺。
1、子域(Subdomain)
在初識子域概念時,可能會認(rèn)為子域與領(lǐng)域的是父子關(guān)系。其實他們并不是父子關(guān)系,而是包含關(guān)系。當(dāng)多個業(yè)務(wù)域(領(lǐng)域)的組合形成了一個更大的業(yè)務(wù)域(領(lǐng)域)時,其中每一個領(lǐng)域(業(yè)務(wù)域)是這個更大的業(yè)務(wù)域的一部分,每一個業(yè)務(wù)域相對于這個更大的業(yè)務(wù)域稱之為這個更大領(lǐng)域的子業(yè)務(wù)域,簡稱子域。組合而成的這個更大的業(yè)務(wù)域統(tǒng)稱為領(lǐng)域。
補充:領(lǐng)域與子域的關(guān)系更好的描述是餅狀圖,領(lǐng)域相當(dāng)于整個餅狀圖,子域相當(dāng)于這個餅狀圖中的某一個塊。
這是一個有關(guān)“零售商在線銷售產(chǎn)品”的例子,來源于《實現(xiàn)領(lǐng)域驅(qū)動設(shè)計》。
把零售商中的所有業(yè)務(wù)看做成一個領(lǐng)域(業(yè)務(wù)域),把這個整體業(yè)務(wù)域中的每一個業(yè)務(wù)域看做成子域。所以這個零售商業(yè)務(wù)域中包括:產(chǎn)品目錄子域、訂單子域、物流子域、發(fā)票子域、庫存子域等。
這張業(yè)務(wù)域圖已經(jīng)為我們呈現(xiàn)了一個近似完整的子域劃分圖。那么這張圖是如何完成劃分的呢?
對一個業(yè)務(wù)域劃分子域時,往往會把一個領(lǐng)域劃分為:核心域、支撐子域、通用子域三種類型的子域集。其中核心域是整個業(yè)務(wù)域(領(lǐng)域)的核心,支撐子域和通用子域完成非核心的業(yè)務(wù)。不管怎么樣,在對一個整體業(yè)務(wù)域進行劃分時,首先要做的是劃分核心域。
注意:三種類型的子域不是三個類型的子域,每種類型的子域數(shù)量可能有多個。
2、核心域(Core Domain)
核心域是整個業(yè)務(wù)系統(tǒng)的核心,所有的業(yè)務(wù)都要圍繞著核心業(yè)務(wù)域展開。如何明確核心域呢?
通常明確核心的方式是精煉業(yè)務(wù)域。精煉是一個持續(xù)的過程,具體來說有以下幾種方式:
-
領(lǐng)域愿景說明(Domain Vision Statement)
-
突出核心(Highlighted Core)
-
內(nèi)聚機制(Cohesive Mechanism)
-
分離的核心(Segregated Core)
-
抽象核心(Abstract Core)
3、領(lǐng)域愿景說明(Domain Vision Statement)
這部分的內(nèi)容在《領(lǐng)域驅(qū)動設(shè)計》中表達地非常簡潔,沒有必要再做過度的解讀。具體內(nèi)容如下:
并且還給出了兩個“領(lǐng)域愿景說明”的示例:
在這兩個示例中提到的模型并不是一個領(lǐng)域模型,而是一組領(lǐng)域模型。更具體地來說是要告訴我們這一組領(lǐng)域模型要解決什么問題,而這個要解決的問題正是由客戶來提出的最需要的那個功能,這個最需要的功能正是業(yè)務(wù)域中的核心。
為業(yè)務(wù)域編寫“領(lǐng)域愿景說明”是有必要的,因為它可以讓整個團隊的人員都能明確什么是核心域。正是明確了核心域,才可以使整個團隊朝著統(tǒng)一的方向前進。
4、突出核心(Highlighted Core)
我們通過“領(lǐng)域愿景說明”可以明確什么是核心域,但這是從一個較為寬泛的角度對核心域進行說明的。我們明確核心域的目的是為了形成核心領(lǐng)域模型,此時我們需要突出核心。
突出核心域中的領(lǐng)域模型有兩種方式:
-
精煉文檔;
-
標(biāo)明核心(Core)。
精煉文檔要做的事情是創(chuàng)建一個最核心的概念對象的清單文檔。
標(biāo)明核心(Core) 要做的事情是從一個完整的領(lǐng)域模型文檔中標(biāo)記出最核心的領(lǐng)域模型。
5、分離的核心(Segregated Core)
分離的核心的主要目的有兩個:
-
將核心域中的非核心元素(模型)分離出去。
-
將非核心域中的核心元素(模塊)移動到核心域中。
這兩個目的都是為了讓核心域更加清晰和增強核心域的內(nèi)聚性。
有關(guān)核心域的更多內(nèi)容請閱讀《領(lǐng)域驅(qū)動設(shè)計》中的第十五章,其中非常詳細地闡述了如何明確核心域和實現(xiàn)核心域。
《實現(xiàn)領(lǐng)域驅(qū)動設(shè)計》中通過問題空間和解決方案空間對核心域做了更直接的說明:
-
問題空間是領(lǐng)域的一部分,對問題空間的開發(fā)將產(chǎn)生一個新的核心域。[IDDD, P48]
核心域的范圍并不一定是一次就能確認(rèn)的,可能需要迭代很多次,每一次都有可能擴大或縮小。
6、通用子域
如果一個子域不是核心域并且被用于整個業(yè)務(wù)系統(tǒng),那么這個子域便是通用子域。[IDDD, P44]
通用子域:模型中有你想當(dāng)然的部分。不可否認(rèn),它們確實是領(lǐng)域模型的一部分,但它們抽象出來的概念是很多業(yè)務(wù)都需要的。比如:各個行業(yè)(如:運輸業(yè)、銀行業(yè)或制造業(yè))都需要某種形式的企業(yè)組織圖。[DDD, P282]
這兩段摘取為我們描述出什么是通用子域,從業(yè)務(wù)域的角度來看,通用子域也是一種業(yè)務(wù)域,和核心域一樣。只是沒有核心域的優(yōu)先級高。因為核心域是整個系統(tǒng)的核心,整個系統(tǒng)因為核心域才具有競爭性。而通用子域只是那些提供的增強功能,比如電商系統(tǒng)中的商品收藏、店鋪收藏、用戶信息等等這些功能,它們確實是電商系統(tǒng)中的業(yè)務(wù),但是并不是核心業(yè)務(wù),這些增強性的業(yè)務(wù)就是通用子域。
注意:有些小伙伴會把通用子域與共享內(nèi)核混淆,是因為共享內(nèi)核的組成部分既有可能是核心域、支撐子域或者通用子域。
7、支撐子域
在業(yè)務(wù)域中,會有一些比較重要的業(yè)務(wù),但卻不是核心,那么它便是一個支撐子域。創(chuàng)建支撐子域的原因在于它們專注于業(yè)務(wù)的某個方面。它不像核心域在整個系統(tǒng)中那么重要,也不像通用子域。
8、開源電商
Mallfoundry 是一個完全開源的使用 Spring Boot 開發(fā)的多商戶電商平臺。它可以嵌入到已有的 Java 程序中,或者作為服務(wù)器、集群、云中的服務(wù)運行。
-
領(lǐng)域模型采用領(lǐng)域驅(qū)動設(shè)計(DDD)、接口化以及面向?qū)ο笤O(shè)計。
項目地址:gitee.com/mallfoundry…
- 總結(jié) -
在一個業(yè)務(wù)域中,基本由三種類型的子域組成,分別是:核心域、通用子域和支撐子域。在分析業(yè)務(wù)域時,首先要做的事情是分析核心域,然后設(shè)計核心域,這樣就能明確系統(tǒng)的最主要的功能。
圍繞著這個核心域進行展開,慢慢添加其它子域,比如通用子域和支撐子域。在開發(fā)核心域和其它子域時,要為核心域分配最高的優(yōu)先級,其它子域可以根據(jù)任務(wù)的多方面因素在分配優(yōu)先級。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!