貧血模型-Martin Fowler 翻譯
作者:Martin Fowler 譯者:劉曉日
貧血模型作為眾多反模式中的一份子,已經有悠久的歷史了,而且現在勢頭正旺。在我與Eric Evans的交談中得知,我們都注意到貧血模型開始越來越流行了。這對於純粹領域模型的忠實粉絲或許不是一件好事兒。
貧血模型一個明顯的特徵是它僅僅是看上去和領域模型一樣,都擁有物件、屬性、物件間通過關係關聯。但是當你觀察模型所持有的業務邏輯時,你會發現,貧血模型中除了一些getter和setter方法,幾乎沒有其他業務邏輯。這種情況事實上是由一些設計規則中(design rules)規定不要把業務邏輯放到“領域模型”中造成的,取而代之的是把所有的業務邏輯都封裝到眾多service中。這些service物件在“領域物件”(領域層)之上形成一個service層,而把“領域物件”當做資料使用。
貧血模型從根本上就違背了物件導向設計將屬性與操作融合的思想。貧血模型就是我們純粹的物件導向忠實者(比如我和Eric)從Smalltalk早期就極力反對的程式導向化設計的風格。更糟糕的是,很多人認為貧血模型就是真正的物件導向,進而也就完全領悟不到物件導向設計的真諦。
純粹的物件導向已經很好了,但是,我知道我需要列出更多的論點去反駁貧血模型。貧血模型一個致命的缺陷就是與領域模型所消耗同樣多的資源,卻沒有得到任何領域模型所具有的優點。這種消耗主要在建立與資料庫的對映上,這樣就單獨劃分出一層專注於O/R對映。當你使用功能強大的物件導向技術時,這樣做是值得的。而這種將業務邏輯統統放到service中是赤裸裸的面向事務程式設計的方式,這樣領域模型所能帶來的優勢消失殆盡。然而就像我在“P of EAA”中所說的那樣,領域模型並不總是“銀彈”。
這裡值得強調一下,將業務行為放到領域模型同使用分層技巧將領域邏輯、持久層和展現層分離是不衝突的。不管你喜歡叫它什麼,領域模型所持有的邏輯(比如驗證、計算、業務規則等)就叫領域邏輯。(有時候你可能會力主在領域物件里加入資料來源或表示邏輯,但這和我說的貧血無關)(注:此句來自豆他爹。超級感謝豆他爹的翻譯,太犀利了,看完我就覺得就是這樣啊,醍醐灌頂的感覺。)
造成物件導向現狀混亂的一個主要因素是許多物件導向專家就建議在領域模型之上增加一個service層。但是這不能作為不把領域邏輯放到領域模型中的依據,事實上service層應該結合領域模型中持有的領域邏輯方法一起使用。
在享譽全球Eric Evans大師的《領域驅動設計》一書中,這樣描述這些層的職責(應用層、領域層翻譯引自《領域驅動設計-軟體核心複雜性應對之道》一書44頁):
應用層(service層):定義軟體要完成的任務,並且只會表達領域概念的物件來解決問題。這一層所負責的工作對業務來說意義重大,也是與其他系統的應用層進行互動的必要渠道。 應用層贏儘量簡單,不包括業務規則或者知識,而只為下一層中的領域物件協調任務,分配工作,使他們互相協作。它沒有反應業務情況的狀態,但是卻可以具有另外一種狀態,為使用者或程式顯示某個任務的進度。
領域層(或模型層):負責表達業務概念,業務狀態資訊以及業務規則。儘管儲存業務狀態的技術細節是有基礎設施層實現的,但是反應業務情況的狀態是有本層控制並且使用的。領域層是業務軟體的核心。
這裡所說的關鍵點是service層很薄(所有業務邏輯都在領域層)。Eric Evans在service層中反覆強調這個觀點:
如今,在實踐DDD過程中最常見的錯誤是,過早的放棄將領域邏輯放到一個合適的領域模型中,從而滑向了過程化程式設計的“深淵”。
如今,不知道為什麼這種反模式可以當道,據我揣測,可能是眾多的開發人員,尤其是有從事資料相關背景的開發人員,根本就沒有使用過純粹的領域模型。有些技術鼓勵使用領域模型,比如J2EE中的實體Bean。這也是我喜歡POJO領域模型的原因。
總之,將越多的領域邏輯放到service中,你就越難體會到領域模型帶來的好處。如果你所有的領域邏輯都在service中,那你得不到任何領域模型帶來的好處。
原文地址:http://martinfowler.com/bliki/AnemicDomainModel.html
宣告,本文為原創翻譯,由於小人才疏學淺,加之第一次翻譯e文,如有不合適的地方,煩請各位指正。
其中有些地方加入自己的理解,如理解錯誤,望見諒。
相關文章
- Martin Fowler大神 - 微服務、貧血模型、重構、敏捷開發方法論微服務模型敏捷
- 從貧血模型到充血模型模型
- 貧血模型 - DDD - The Domain Driven Design模型AI
- Martin Fowler:繼承是被誤用了繼承
- 貧血模型與充血模型比較 - DDD - The Domain Driven Design模型AI
- 敏捷史話(八):敏捷的破局之道——Martin Fowler敏捷
- 聊一聊領域驅動與貧血模型模型
- Martin Fowler三萬字解讀原始碼分支管理模式原始碼模式
- 高質量的軟體是否能賺回成本? - Martin Fowler
- 瀑布和迭代可混合:敏捷定義者Martin Fowler定義瀑布法敏捷
- 幽默:請不要用“型別1 2 3 ..”來區分事物 - Martin Fowler型別
- 談DDD與貧血領域模型:再次為失血模型辯護 -Codecentric AG部落格模型
- 監管機器翻譯質量?且看阿里如何搭建翻譯質量評估模型阿里模型
- 線上文字翻譯能力新增14個直譯模型,打造以中文為軸心語言的翻譯系統模型
- 翻譯
- Laravel Baum 巢狀集合模型中文文件翻譯-部分Laravel巢狀模型
- Detectron2-寫模型(Write Models)官方文件中文翻譯模型
- 蝴蝶書-task2: 文字推理、摘要、糾錯 transformers實現翻譯 OpenAI翻譯 PyDeepLX翻譯 DeepLpro翻譯ORMOpenAI
- Ubuntu安裝劃詞翻譯軟體Goldendict 單詞翻譯 句子翻譯UbuntuGo
- 如何完成中文翻譯日文線上翻譯
- Laravel 谷歌翻譯 /Bing 翻譯擴充套件包Laravel谷歌套件
- OpenCV翻譯專案總結二——Mat翻譯OpenCV
- 騰訊互動翻譯的坑爹翻譯
- MapLibre/Martin | 使用Martin釋出MBTiles地圖切片包地圖
- 使用google翻譯 api 翻譯中文成其他語言GoAPI
- 文件翻譯器怎麼用?如何翻譯Word文件?
- 有道雲詞典--翻譯/螢幕取詞翻譯
- TailWind文件翻譯說明以及每日翻譯進度AI
- 翻譯介面整理
- Python 谷歌翻譯Python谷歌
- 翻譯軟體
- 翻譯|Thinking StatefullyThinkingStatefully
- MPAndroidChart文件翻譯Android
- bulma中文翻譯
- 歌詞翻譯
- socket中文翻譯
- 詞典翻譯 英譯漢
- Arctime怎麼翻譯字幕?Arctime批次翻譯字幕的技巧
- Python 使用白嫖網易翻譯 API 進行翻譯PythonAPI