領域驅動系列:澄清一些基礎概念

剛哥521發表於2015-04-26

要研究DDD,必須認清DDD的核心是通用語言和模型驅動設計。即使是DDDLite(技術上的DDD),也必須清楚DDD在架構中的位置和必須的架構知識,否則一路跑到哪裡能否回來都是未知了。我們先了解常用架構分層,再瞭解DDD的所在層次和範疇,然後強調DDD的核心。包括從架構到領域模型設計方面的決策和自己的些許實踐。

 

1.三層作為基礎:表示層、業務邏輯層、資料訪問層是所有討論的基礎。

有2個最重要的決策和實踐等待你應用和發現:

 

(1)在假設存在多個表示層的基礎上,你可以據此將分散在表示層中的業務邏輯程式碼從其中分離。

(2)在假設需要支援不同種資料來源的的基礎上,你可以將分散在業務邏輯層的資料訪問層程式碼從其中分離出來。

這意味著大多數情況你不用冥思苦想、搜腸刮肚的去搞明白到底什麼是三層,如果你書讀的多,可以從書中看到這些原則;如果你程式碼寫的多又習慣重構你會自然發現這些原則。發現和在重構中應用這些原則是最重要的,完全不可能存在【努力太少,想的太多】的方式搞清這些。

 

2.四層作為核心:將業務邏輯層分離為應用層和領域層是領域驅動設計的架構方面的核心。

同樣有2個最重要的決策和實踐來保持領域層的純粹:

 

(1)將表示層必須的業務邏輯呼叫以應用介面的方式分離到應用層。其他無需公開的部分分離到領域邏輯層。

(2)將業務邏輯對具體技術的依賴轉換為介面依賴,將介面的定義和呼叫分離到應用層中。

這意味著即使不考慮領域模型的組織形式,我們也可以將應用層和領域層大體上理清。你需要動手,只看是不行的。大多數問題都經不住實踐,重構後大多數問題實際上都不存在,你會總結出這些實踐,但是你的程式碼也不會完整的反應出這些原則,那是因為這本身就是架構層次上的決策,沒有任何框架和演示能將架構上決策的東西完美體現出來。完全不可能存在【只看程式碼】的方式搞清這些。

 

3.領域模型的組織形式:實體、值物件和領域服務只是領域模型的一種組織形式。

必須注意2點:

 

(1)領域模型的組織形式是領域層的範疇。

(2)是否採取經典DDD領域模型的組織方式對架構層次沒有影響。

這裡終於到了領域驅動設計相關的概念了,之前討論都是的架構方面的,可以說是無關領域驅動的。領域驅動設計的核心是什麼?設計是一個過程,領域驅動是一個原則。在領域驅動的原則下進行設計,設計的結果是一系列主要在領域層範疇的模型。如果自己總結不出來,可以去看經典DDD的附錄領域驅動設計關係圖的人都知道的兩個核心:通用語言和模型驅動設計。因此談論DDD必須要結合具體的領域邏輯和設計中的各種決策以及結果,即使是DDDLite(技術角度的DDD)也不應該因為領域驅動設計中涉及到了很多架構方面的概念就認為這些概念屬於領域驅動設計。至少應該清楚DDD的架構無關性。

 

4.領域模型的結果:

 

(1)建模的結果由領域邏輯決定,結果包含一種或多種型別(實體、值物件和領域服務)的一個或多個模型

(2)如果領域邏輯只是簡單計算過程,那麼模型可能只是包含一個方法的一個領域服務。

(3)如果領域邏輯偏向資料管理,模型可能主要由一系列關聯的實體組成,這些實體的形式上和貧血模型一致。

由於大多數的應用程式的領域邏輯都比較簡單,偏向過程和資料操作,因此領域模型顯得不夠豐富,但這都是領域邏輯自然分析得到的結果。在不斷的重構中,實體和領域服務會逐漸的將應用層中的領域邏輯程式碼分離出來。

 

5.實體:

 

(1)如果業務邏輯用過程表達更適合,實體沒必要存在。

(2)實體對應集合和型別的概念,同種實體的多個物件都是唯一的。因此論壇領域(板塊、主題、評論)和電商領域(分類、產品、訂單)這些都是自然而然的實體型別。

6.值物件:

 

(1)如果實體比較簡單,值物件沒必要存在。

(2)值物件對於列舉和狀態的概念。值物件作為實體屬性的一部分。這些值物件本質上是沒有任何差別的。因此論壇領域(主題狀態)和電商領域(交易型別、訂單狀態)這些都是自然而然的值物件。

 

7.領域服務:

 

(1)如果實體的方法可以修改為靜態方法,那麼這個方法更適合置於領域服務中。

(2)如果我只對領域層進行單元測試,必須反覆寫一些出現在應用層的程式碼來協調領域邏輯,那麼這些程式碼很可能屬於領域服務。

 

8.總結:

 

(1)在應用DDD之前至少要達到能夠正確的認識三層。如果這點都達不到,不可能成功應用。大體上程式碼都不知道寫哪裡,還談什麼分離領域。

(2)前期必須在架構和建模方面儘量做到層次分明和概念清晰,後期邊重構邊新增功能比不重構新增功能更快,最怕的是認識不上去而不是沒有解決方案。

(3)不是必須掌握所有的DDD知識和概念才能應用DDD。DDD的核心是通用語言和模型驅動設計

(4)DDD是一個過程,這個過程在不斷的重構中得到最適合的設計和程式碼,因此不要為了DDD而DDD。

 

順便推薦一下ASP.NET設計模式這本書,這本書和作者之前的一些書及其原始碼是這些年國內各大部落格論壇的99%的所謂各種框架和原創文章和出版圖書的來源。作者的成功在於類似科普的手法讓大家把模式和程式碼直接展示給大家,失敗的是國內萬年不變的抄襲風格依然沒有放過這本書,大把大把二次加工出各種文章、帖子、討論和圖書。但這不是作者和其作品的失敗,而是我們這些披著原創的帽子的抄襲者的悲哀。架構方面的知識,本身必須有多個專案經驗的實踐才能有切實的優缺點體會和認知,DDD更是必須有複雜業務邏輯方面的逐漸重構經驗才能有所積累和體驗。要想有所進步,處處離不開思考和重構。在國內這種技術社群的氣氛下,實踐類的不被推崇,偽技術文(標題黨+圖片黨+程式人生黨)和偽原創(抄襲國外圖書、部落格特意宣告為原創的)大行其道,如果你看了好幾年部落格覺得沒看到有用的文章,或操作性不強或根本無法推敲,靜下心來,開始閱讀國外的技術書籍和部落格,開始重構你的程式碼,收穫會日積月累。

 

相關文章