背景
- 最近公司開始推行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思想中的充血模型到底優勢在哪里呢?適用于哪些場景呢?而我們都在用貧血模型,但是我們在平時的開發中也沒有什么問題呀?
為什么大家都在使用貧血模型?
- 使用貧血模型的傳統開發模式,將資料與業務邏輯徹底分離,通過get set方法改變物件屬性,物件屬性可以隨意被修改,這也就如上面所說違反了OOP的三大特性之封裝特性,這樣的編程方式也就是面向程序的編程方式,面向程序的編程方式是符合人類大腦邏輯的,不用使用太多的設計模式和過多的設計,還有就是在開發中大家經常說的一句及其不負責任的一句話:“怎么方便怎么來”,就一直在堆代碼,完全不像以后的可拓展性,也就是說基于貧血模型的編程方式是面向程序編程,人類的思考邏輯方式很符合,在編程程序?也很方便,所以大家都很愿意接受這種編程方式,
- 綜上所述:
- 充血模型的設計要比貧血模型更加有難度
- 大家一致使用基于貧血模型的面向程序編程已經成為習慣,比較難轉換思想
- 還有就是對代碼不負責任的態度,(這是大數程式員的通病吧)
是所有的場景都適合使用充血模型嗎?
- 使用充血模型也就是使用基于充血模型的DDD的開發模式,上文也一再強調,充血模型也是定義模式復雜,設計難等,代碼開發量也許時其他模型的多,其主要原因還是設計起來難,那就是說如果我們設計一個很簡單的業務邏輯,那我們還需要這么復雜的設計思想嗎? 并且這個業務在后續的迭代也不變復雜,那我個人認為我們就使用我們的基于貧血模型的面向程序的編程思想,簡單的東西何必復雜化呢,這里突然想到我同時講的一個段子:
- 普通程式員寫hello word 直接print
- 高級程式員寫hello word 各種設計模式各種可拓展最后輸出hello word
- 技術專家寫hello word ,直接列印hello word
- 當然我們在進行一個復雜的業務場景,那就需要進行基于充血模型的DDD(領域驅動模型)開發模式了,其實DDD的開發模式也就是充分的遵循OOP發三大特性(或者四大特性,封裝,繼承,多型,(抽象)),如果是貧血模型的面向程序編程那到最后的結果就是點練成線,由線變成網,密密麻麻不可維護,所以說復雜業務邏輯基于充血模型的進行開發,但是也會是有問題的那就是類膨脹,一個類有很多代碼,這個還是可以解決的,那就是通過設計模式,喝業務邏輯細分進行解決,
總結
- 貧血模型和充血模型的簡單解釋
- 以及DDD開發模式和面向程序編程與充血和貧血模型的關系
- 對比了基于貧血模型的MVC層的面向程序編程范式和基于充血模型的面向物件編程范式的對比
- 兩種模型分別適用于那種場景
參考
- 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的基礎理論喝
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/181415.html
標籤:其他
