領域驅動設計(DDD)部分核心概念的我的理解
- 領域驅動設計(DDD)是一種基於模型驅動的軟件設計方式。它以領域爲核心,分析領域中的問題,經過創建一個領域模型來有效的解決領域中的核心的複雜問題。Eric Ivans爲領域驅動設計提出了大量的最佳實踐和經驗技巧。只有對領域的不斷深刻認識,才能獲得一個解決領域核心問題的領域模型。若是一個應用的複雜性不是在技術方面的,而是在領域自己,即領域內的業務很複雜,那這種應用,使用領域驅動設計的價值就越大。
- 領域驅動開發也是一種敏捷開發過程(極限編程,XP),強調迭代開發。在迭代過程當中,強調開發人員與領域專家須要保持密切的合做關係。極限編程假設咱們能經過不斷快速重構完善設計。因此,對開發人員的要求很是高。
- 領域驅動設計提出了一套核心構造塊(Building Blocks,如聚合、實體、值對象、領域服務、領域工廠、倉儲、領域事件,等),這些構造塊是對面向對象領域建模的一些核心最佳實踐的濃縮。這些構造塊可使得咱們的設計更加標準、有序。
- 統一語言(Ubiquitous Language),是領域驅動設計中一個很是重要的概念。任何一個領域驅動設計的項目,都須要一種通用語言,一套通用的詞彙。由於沒有通用的語言,就沒有一致的概念,溝通就會遇到障礙,最後的領域模型和軟件也就沒法知足領域內的真實業務需求。通用語言是領域專家和開發人員在對領域問題的溝通、需求的討論、開發計劃的制定、領域模型的設計,以及開發人員之間對領域模型的具體編碼落地實現,等一系列過程當中,全部人員使用的一種通用語言。話句話說,就是不管是溝通時所用的詞彙、仍是領域模型中的概念、仍是代碼中出現的類名與方法,只要是相同的意思,那就應該使用相同的詞彙。能夠看出,這種通用語言不是一會兒就能夠造成,而是在一個各方人員討論的過程當中,不斷髮現、明確,與精煉出來的。
- 領域模型是領域驅動設計的核心。統一語言中的全部關鍵詞彙,在領域模型上應該都能找到。各方人員溝通時,都應該以領域模型爲基礎。經過討論的不斷深刻,你們對領域的認識也會不斷深刻,領域模型也會不斷獲得完善,統一語言的詞彙也會不斷豐富和精準。須要特別強調的是,開發人員應該儘可能保證代碼實現和領域模型相綁定,時刻保持代碼與模型的一致。若是不綁定,那代碼就會慢慢和模型相脫節,就會出現像咱們之前那樣的設計文檔和代碼相脫節同樣的問題,甚至模型還會起到誤導做用。經過這樣一種思路,咱們確保語言、模型、代碼三者緊密綁定,確保最後實現出來的軟件能夠準確無誤的實現業務需求,而且還能讓咱們的軟件能夠快速的和業務同時演進。而不像傳統的開發方式那樣,分析、設計、實現三個階段徹底脫節,最後出來的軟件沒有很好的知足業務需求,也不能在將來很快的跟業務需求一塊兒演進。因此,領域模型同時承載了分析的結果和設計的結果,這裏的分析是指對領域內業務需求的分析,設計是指對模型的設計以及軟件的設計。因此,咱們的領域模型,不能只考慮業務需求,還要同時考慮軟件設計的原則,是一種綜合考慮的、平衡的設計結果。
- 領域模型能夠複用,由於特定的領域模型解決的都是某個特定的問題域;好比淘寶網有個商品中心,有個商品模型,核心概念有商品分類、商品;商品模型負責解決電子商務領域中的商品目錄(Product Catalog)子域。後來阿里又出了個天貓,也會有商品中心,可是這兩個商品中心基本是同樣的問題域。因此,咱們能夠複用以前淘寶實現的商品中心領域模型,並複用以前淘寶商品中心的解決方案,來解決天貓的商品維護和展現。固然,這個只是我我的的認識,一個例子。具體阿里是不是一個商品中心同時解決淘寶和天貓的業務,沒具體調研過。
- Bounded Context,屬於一種軟件構件,做用是用來對領域模型進行劃分。Bounded Context有兩層含義:
- Bounded,即有邊界的,表示領域模型有邊界;這個邊界定義了模型的適用範圍,以便讓負責該模型的團隊知道什麼該在模型中實現,什麼不應;
- Context,即領域模型的產生是在某個上下文中產生的;上下文是一個和環境相關的概念。好比一次頭腦風暴會議你們達成了一個模型,那此次會議的討論就是該模型的上下文;好比某本書中談到了某個東西,那這個東西的上下文就是那本書,那個東西要有意義的前提離不開那本書這個上下文;因此,上下文是模型有意義的前提;
- 領域建模的方法有不少種,我分享一下本身的一種基於場景爲核心的分析方法。大概的思路是:
- 經過與領域專家和業務需求人員溝通,找出領域中的關鍵業務場景;
- 針對每一個業務場景分析出有哪些場景參與者,哪些參與者以對象(聚合)的形式參與,哪些參與者以服務的形式參與;
- 分析每一個場景參與者對象的基本狀態特徵;
- 分析每一個場景參與者對象分別扮演什麼角色參與場景,整個場景的完整交互過程是怎樣的,對象在參與場景的過程當中執行了哪些交互行爲;
- 分析如何記錄和跟蹤這一次交互行爲,分析此次交互行爲會產生哪些額外的信息;
- 上面,只是簡單列了一下條目,具體的描述,請參看個人另外一篇文章,有詳細的敘述。
- 關於領域(Domain)、領域模型(Domain Model)、邊界上下文(Bounded Context)的關係
- 領域就是問題域,問題空間;
- 領域模型是一種模型,表達了領域中哪些業務需求以及業務規則必須被知足;
- 每個領域中的問題,都會有一個對應的領域模型去解決;
- Bounded Context的做用是用來對領域模型進行劃分;
- 劃分領域就是對問題空間的劃分,通俗的理解,就是將大問題拆分爲小問題;
- 劃分Bounded Context就是將一個大的領域模型劃分爲多個小的領域模型;
- 能夠把Bounded Context當作是一種解決方案空間,因此,Bounded Context也能夠理解爲是對解決方案空間的劃分;
- 理論上,一個Domain可能會對應多個Bounded Context;一樣,一個Bounded Context可能也會對應多個Domain;因此他們之間沒有絕對的關係。主要是他們劃分的依據不一樣,一個是針對領域(問題空間),一個是針對領域模型(解決方案空間);理想狀況,一個Domain最好對應一個Bounded Context;
- 關於Domain、Sub Domain、Core Domain、Generic Domain,以及Shared Kernal的理解:
- 一個領域(Domain)會拆分爲多個子領域(Sub Domain);
- 子領域中最核心(最重要)的那個叫Core Domain;咱們應該講團隊的核心資源用在覈心子域上,由於它是產品成敗的關鍵;
- 除了Core Domain外,其餘的是支撐子域(Supporting Subdomain);
- 有些支撐子域比較特殊,由於它解決的是一類通用問題,好比帳號和權限;這類子域咱們叫作通用子域(Generic Subdomain);一般,通用子域對應的Bounded Context,會跨域多個子域;
- 多個子領域有時會有相交的部分,咱們稱做共享內核(Shared Kernel);體現到代碼上,就是同一份代碼,在兩個領域模型中複用;
- 通常只有Domain比較大的時候,咱們纔會劃分出Sub Domain;
- 爲何一個大的領域模型須要劃分?由於,一般一個大的領域模型須要多個團隊合做完成。若是多個團隊基於一個共同的領域模型工做,因爲每一個團隊的關注點不一樣,且一些看似叫法同樣的概念,對於不一樣的團隊,其背後的意思徹底不一樣。因此,這樣的概念含義模糊會給團隊以及成員之間的合做帶來很大的困擾。因此,咱們須要經過一種手段(Bounded Context),將領域模型劃分爲不一樣的部分,確保同一個Bounded Context內的領域模型所表達的概念含義明確。而後,同一個Bounded Context下面,相關人員都使用一種統一的語言,以此來保證團隊成員之間溝通能暢通無阻;
歡迎關注本站公眾號,獲取更多信息