理解领域模型
大概從去年開始,就開始覺得,我一直在寫的Java根本是面向過程的。并且絕大多數的代碼都非常丑陋,那些封裝,抽象,設計模式。壓根沒有一點用武之地。我很努力的在項目中盡量讓我的代碼顯的優美,可收效甚微。于是我懷疑,是不是這很多書中所謂的“三層框架”從一開始就是有問題的。
之后在《輕量級JavaEE企業應用實戰 Struts2 Spring3 Hibernate整合開發》讀到了相關的架構設計策略。網上搜索才知道,原來不止我一個人有各種懷疑。javaeye很久以前就有次關于domain object的大討論了。
?
網上的資料不多,一般有兩種分類:
貧血模型、領域模型,這種分類方法應該來自Martin Fowler的《企業應用架構模式》。
失血模型、貧血模型、充血模型、脹血模型,這種分類方法可能是在javaeye上的robbin提出的,我不太確定。
?
作為學習資料,這里使用更為標準的領域模型的相關概念。
?
貧血模型
只有get/set的model,Dao,還有Service。
service處理業務邏輯。其本質和存儲過程其實也沒啥大差別,即事物腳本。
貧血模型的包結構:
- dao:負責持久化邏輯。
- model:包含數據對象,是service操縱的對象。
- service:放置所有的服務類,其中包含了所有的業務邏輯。
- facade:提供對UI層訪問的入口。
這就是很多書里介紹的“三層架構”。代碼寫到現在,我做過的所有項目都這樣寫的,連C#都不例外。當業務邏輯復雜,service便會變得無比龐大,維護非常困難。還有這種模型根本就不面向對象,最多只能算基于對象。更可惡的是,似乎大家都以為這才是標準。
對于業務邏輯簡單的項目,貧血模型是可以使用的。但業務復雜后,即應避免貧血。或重構代碼時去除貧血。
?
領域模型(domain model)
現在比較公認的領域模型是將與持久化無關的業務邏輯放入model中,dao負責持久化。service負責跨領域的業務邏輯。
更加面向對象,且實現方法清晰,易于控制。
但有個問題就是,service中包含了DAO的持久化方法,還不是純粹的業務邏輯處理。
- infrastructure: 代表基礎設施層,一般負責對象的持久化。
- domain:代表領域層。domain包中包括兩個子包,分別是model和service。model中包含模型對象,Repository(DAO)接口。它負責關鍵業務邏輯。service包為一系列的領域服務,之所以需要service,按照DDD的觀點,是因為領域中的某些概念本質是一些行為,并且不便放入某個模型對象中。比如轉帳操作,它是一個行為,并且它涉及三個對 象,fromAccount,toAccount和TransferTransaction,將它放入任一個對象中都不好。
- application: 代表應用層,它的主要提供對UI層的統一訪問接口,并作為事務界限。
?
?
富領域對象(rich domain model)
將model與dao相結合。也即將持久化方法放入model中。
這樣就帶來一個難點,service與model怎么劃分。
實現需要深刻的理論與豐富的經驗。難度較大。
?
據說,ROR實現該模型非常方便,看來有必要學習一下Ruby。
?
由于Service與model難于劃分,所有有人提出廢除service。所有的業務邏輯都放在model中。
完全消除分層,事物沒法控制,且無法將會由web層控制業務邏輯。這是比貧血模型更應該摒棄的。
?
對領域模型的一個疑問:在團隊開發中,由于每個開發者水平層次不齊。如何保證每個領域內的業務邏輯可以在各個不同開發人員之間協作開發呢?
?
?
參考資料:
http://www.iteye.com/topic/17579
http://www.iteye.com/topic/283668
《輕量級JavaEE企業應用實戰 Struts2 Spring3 Hibernate整合開發》
轉載于:https://www.cnblogs.com/shijiaqi1066/p/3349774.html
總結
- 上一篇: oracle-Oracle试题
- 下一篇: 例3-2