DDD(領域驅動設計),你必須知道的貧血模型和充血模型

2020-10-19 11:00:26

背景

  • 最近公司開始推行DDD(領域驅動設計),基於充血模型的物件導向開發模式是DDD的特點之一,而在平時開發中我們都使用的是MVC 架構是基於貧血模型的程式導向開發風格,也許有同學就會問了,貧血模型和充血模型是的什麼呢?

貧血模型和充血模型

簡介

貧血模型

  • 定義物件的簡單的屬性值,沒有業務邏輯上的方法(個人理解)沒有找到官方解釋

充血模型

  • 充血模型也就是我們在定義屬性的同時也會定義方法,我們的屬性是可以通過某些方式直接得到屬性值,那我們也就可以在物件中嵌入方法直接建立出一個具有屬性值的物件。也就是說這個物件不再需要我們在進行進一步的操作,這也就複合了OOP的三大特性之一的封裝(個人理解)

關於DDD和充血模型的關係

我們在平時進行web開發的時候,就是定義DTO,定義資料庫Model,BO等,對其進行get set方法,然後通過service 對Bo物件進行操作,最後通過copy屬性持久化資料庫和DTO傳輸。但是如果是充血模型的話,就不用在service進行屬性賦值,而是在建立這個物件的時候,進行業務操作,賦予其屬性值。這裡也就是DDD的思想,這個物件也就是DDD所定義的Entity 或者 value 。Service也就是domianService,由多個Entity 和value 組成,構造最終的領域模型。

下圖是作者本人對DDD的理解畫的圖,也希望能幫到大家理解:
在這裡插入圖片描述

迴歸正題還是看充血模型和貧血模型
說了這麼多DDD思想中的充血模型到底優勢在哪裡呢?適用於哪些場景呢?而我們都在用貧血模型,但是我們在平時的開發中也沒有什麼問題呀?

為什麼大家都在使用貧血模型?

  1. 使用貧血模型的傳統開發模式,將資料與業務邏輯徹底分離,通過get set方法改變物件屬性,物件屬性可以隨意被修改,這也就如上面所說違反了OOP的三大特性之封裝特性。這樣的程式設計方式也就是程式導向的程式設計方式,程式導向的程式設計方式是符合人類大腦邏輯的,不用使用太多的設計模式和過多的設計。還有就是在開發中大家經常說的一句及其不負責任的一句話:「怎麼方便怎麼來」,就一直在堆程式碼,完全不像以後的可拓展性。也就是說基於貧血模型的程式設計方式是程式導向程式設計,人類的思考邏輯方式很符合,在程式設計過程️也很方便,所以大家都很願意接受這種程式設計方式。
  2. 綜上所述:
  • 充血模型的設計要比貧血模型更加有難度
  • 大家一致使用基於貧血模型的程式導向程式設計已經成為習慣,比較難轉換思想
  • 還有就是對程式碼不負責任的態度。(這是大數程式設計師的通病吧)

是所有的場景都適合使用充血模型嗎?

  1. 使用充血模型也就是使用基於充血模型的DDD的開發模式,上文也一再強調,充血模型也是定義模式複雜,設計難等,程式碼開發量也許時其他模型的多,其主要原因還是設計起來難。那就是說如果我們設計一個很簡單的業務邏輯,那我們還需要這麼複雜的設計思想嗎? 並且這個業務在後續的迭代也不變複雜,那我個人認為我們就使用我們的基於貧血模型的程式導向的程式設計思想。簡單的東西何必複雜化呢。這裡突然想到我同時講的一個段子:
- 普通程式設計師寫hello word 直接print 
- 高階程式設計師寫hello word 各種設計模式各種可拓展最後輸出hello word 
- 技術專家寫hello word ,直接列印hello word
  1. 當然我們在進行一個複雜的業務場景,那就需要進行基於充血模型的DDD(領域驅動模型)開發模式了。其實DDD的開發模式也就是充分的遵循OOP發三大特性(或者四大特性,封裝,繼承,多型,(抽象)),如果是貧血模型的程式導向程式設計那到最後的結果就是點練成線,由線變成網,密密麻麻不可維護。所以說複雜業務邏輯基於充血模型的進行開發。但是也會是有問題的那就是類膨脹,一個類有很多程式碼。這個還是可以解決的,那就是通過設計模式,喝業務邏輯細分進行解決。

總結

  1. 貧血模型和充血模型的簡單解釋
  2. 以及DDD開發模式和程式導向程式設計與充血和貧血模型的關係
  3. 對比了基於貧血模型的MVC層的程式導向程式設計正規化和基於充血模型的物件導向程式設計正規化的對比
  4. 兩種模型分別適用於那種場景

參考

  • https://time.geekbang.org/column/article/169600 設計模式之美
  • https://zh.wikipedia.org/wiki/%E5%8F%8D%E9%9D%A2%E6%A8%A1%E5%BC%8F 反面模式
  • http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html DDD的基礎理論喝