再論 Java 應用中的“領域建模”
轉載請保留作者信息:
作者:88250
Blog:
http:/blog.csdn.net/DL88250
MSN & Gmail & QQ:DL88250@gmail.com
最近又重新整理了一下項目中領域模型建模的思路。記得范凱(
robbin
) 在 2005 年時候總結的四種風格的“領域模型”及其一些變種相信大家的耳熟能詳了。以現在的觀點來看,不管其劃分是否合理,是否適合任何項目,討論都是有意義的。從 2004 年到 2008 年來領域模型的話題一直都是各個技術論壇、郵件列表必討論的話題之一,這里我只是想就‘領域模型建?!@個問題發表一下我的觀點,相信討論還會繼續下去,這才是本質——演化。這里的觀點都是基于 Java 環境上的應用展開的,其他語言環境另當別論。
相關術語與概念
首先,讓我們澄清一些相關術語與概念。很多時候發現大家討論問題前都沒有一個共同的基本假設作為前提,導致了問題越討論越混亂,引入的其他問題越來越多。這里,我先對本文涉及的幾個非?;镜母拍钭鰝€統一的假設。
POJO(
Plain Old Java Object
)
POJO 是一個簡單的、常規的 Java 對象,它包含業務邏輯處理或持久化邏輯等,但不是 JavaBean、EntityBean 等,不具有任何特殊角色并且不繼承/不實現任何其它 Java 框架的類或接口(java.io.Serializable 除外)。例如下面這個類就是一個 POJO,注意業務邏輯方法:
/**
* A POJO user description.
* @author
88250
* @version 1.0.0.0, Jan 15, 2009
*/
public class User implements Serializable {
/**
* user name.
*/
private String name;
/**
* Default constructor.
*/
public User() {
}
/**
* User login business logic.
*/
public void login() {
// ....
}
/**
* Gets the name of this user.
* @return the value of
name
*/
public String getName() {
return name;
}
/**
* Sets the name of this user.
* @param name new value of
name
*/
public void setName(String name) {
this.name = name;
}
}
從 OO 的角度看,這是一個純粹的 Java 類,它擁有狀態與行為,這也就構成了這個 User 類的職責??上КF在 POJO 這個詞簡直是濫用啊,大家都認為只要描述的是一個領域
實體,一個純數據類就是 POJO 了
。
領域模型(
Domain Model
)
根據 Martin 大叔的解釋,領域模型就是統一了 行為 與 數據 的 對象模型 。從 OO 的角度上看是沒有任何難點與疑問的,但是開始對具體項目著手進行 OO 設計的時候問題就很多了,后面將闡述一些在實施領域模型建模時“公認”的問題。再來看看 Wikipedia 上關于 領域模型的解釋 ,其中涉及到了“領域層( Domain Layer ) ”這個概念,并且說明了 DDD 中的領域模型是領域層的一個部分 。如下圖:
根據 Wikipedia 上的解釋,領域層與 業務層 是同一個概念,這樣劃分的確是純粹的 DDD。不過,這與 JavaEE 規范中的分層理念有一點沖突,與 EJB 3 編程模型有著明顯的沖突。
各種風格(Style)的領域模型
這里的“風格”是按照 Martin 的觀點進行闡述的。在 以往的討論 中,有四種可行的模型:
- 失血模型
- 貧血模型
- 充血模型
- 脹血模型
這四種模型基本是
robbin
、
JavaEye
社區思考、討論的結果。但我認為還是按照 Martin 的提出的模型進行討論比較簡潔,有兩種可行的模型:
- 貧血的領域模型(Anemic Domain Model)
- 富領域模型(Rich Domain Model)
貧血的領域模型( Anemic Domain Model )
貧血的領域模型就是在領域對象中 只 包含了 accessors 方法,默認的構造器,不包含任何邏輯處理。而邏輯處理放置于 xxxManager 中,使用事務腳本( Transaction Script , PoEAA )進行操作。
富領域模型(
Rich Domain Model
)
富領域模型就是 DDD 中所描述的模型,完全的 OO Concerns 。
“公認”的問題
EJB 3 & JPA
眾所周知,EJB 3 + JPA 的編程模型是典型的貧血模型,也是 JavaEE 所推廣的 最佳實踐 ,唯一正統的編程模型。 在這個模型中,EJBs 扮演了業務邏輯處理的角色,在分層設計中處于服務層 / 業務層。而 JPA entities 則扮演了典型的 純稚數據類 ,其行為完全由 EJBs 負責。這些也許與早先的 SSH 這樣一個 無狀態 框架組合那么深入人心密切相關吧。目前來說,Seam 框架 / WebBeans 規范是解決客戶端與服務端狀態問題的較好實現與規范。另外,Seam 中的 Entity 也是可以作為 Component 而 inject / outject 的,所以 Seam 有在嘗試 提供一個 DDD 的框架給開發者。
Domain Logic vs Business Logic
如果你是一個 DDD 的純粹擁護者,不存在區分領域邏輯與業務邏輯,統稱為領域邏輯。下面這個劃分領域邏輯與服務邏輯是針對類 EJB 3 + JPA 純粹用戶者的。
Domain 業務邏輯(Domain Logic)與 Service 業務邏輯(Business Logic)劃分的原則:
-
根據是否依賴持久化邏輯劃分
領域模型只包含不 依賴于持久化 的領域邏輯,而那些依賴持久化的領域邏輯應該被分離到 Service 層 -
使用 Rod Johnson 的"case by case"原則
可重用度高的,和 domain object 狀態密切關聯 的放在 domain 中,可重用度低的,和 domain object 狀態沒有密切關聯的放在 Service 中
這樣,貌似是解決了 Java 應用中使用“正統”方式(JavaEE 規范)實現領域驅動開發。但是,這樣不覺得過于復雜和畫蛇添足嗎?
結論
領域模型驅動的設計(DDD)是需要開發團隊在特定行業中 積累 到一定的時候才能真正做到的,這涉及到了企業(客戶)的核心價值實現與業務實現 重用 ,如果不是本著這個 最終目的 ,Java 下的 DDD 慎用。在建模你的 Java 項目時,一定要對項目的 Scope 做好分析,認真做好技術選型。一般來說,貧血模型(Anemic Domain Model)是最容易設計和實現的,也足夠滿足一般 Java Web 項目了。而領域模型(Rich Domain Model)是用在復雜 JavaEE 項目上的(例如實施 SOA 時),切勿殺雞用牛刀 :-)
參考列表
下面的文章是精華中的精華,有興趣、時間的朋友一定不要錯過 :-)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
