天天看點

openfans領域模型驅動的嘗試

領域模型驅動( Domain Driven Design ),很熱的名詞。 Openfans ,不太熱的網站。今天俺就借着很熱的 ddd ,給不太熱的 openfans 再造點勢。 Openfans 就不多介紹了,網站用 spring+hibernate 為核心的一堆開源軟體建構。有了 spring 的 IOC 和 hibernate 的 ORM ,打着 ddd 的旗号也就名正言順了很多。先聲明其實俺對 ddd 的了解也多是道聽途說,沒有什麼系統的學習過,倒是和 Joe 阿牛讨論過幾次,頗有受益,他對這個了解還是很深刻的。

言歸正傳,就講 openfans 現在經 ddd 思想改造過的模型。整體上看還是普通的三層架構體系:展現層、業務層、持久層。展現層用 spring mvc ,力圖做到隻是展示相關,避免出現業務邏輯。再具體細分,就是 jsp 頁面隻有展示邏輯,主要使用 jstl 完成顯示功能。 Controller 負責從頁面獲得參數、把資料傳回頁面、控制頁面流傳和調用業務層的接口。持久層使用 hibernate ,在設計上我不是按 dao 方式為每個對象建立相應的 dao ,也不是 ddd 推薦的每個 domain 一個 repository ,而是分成了 Persistence 和 Fetcher2 個接口。 Persistence 處理持久相關如 save 和 remove 方法, Fetcher 則處理 get 相關。這樣分的原因也很簡單, persistence 是很穩固的,對象都可以共用一個接口如 save ( Object ),而 fetcher 就千變萬化,需要分頁、排序等接口。

這樣設計是與業務層架構相關的。我采用的是 domain 對象(簡稱 DO ) + 一層薄薄 façade 的方式。 DO 處理自身的邏輯,包括持久功能。本身 DO 是沒有持久能力的,需要依靠注入的 persistence 接口,這裡就展現按 Persistence 和 Fetcher 分開的一個好處, persistence 所有 DO 可以共用一個,給程式設計帶來了友善。 Openfans 中采用的是 DO 繼承一個抽象 PersistentObject 類的方式,這樣 DO 友善的獲得了注入的能力和持久的能力。這樣做有何優缺點還需要做些讨論,為了友善我也就先這麼用。 PersistentObject 代碼如下:

public abstract class PersistentObject implements NeedPersist {

       private Persistence persistence;

<o:p> </o:p>

       public void save() {

              persistence.save(this);

<o:p> </o:p>

       }

<o:p> </o:p>

       public void remove() {

              persistence.remove(this);

       }

<o:p> </o:p>

       public void setPersistence(Persistence persistence) {

              this.persistence = persistence;

       }

<o:p> </o:p>

       public Persistence getPersistence() {

              return persistence;

       }

}

這樣 DO 隻需要注入 persistence 就獲得了持久的能力,而且可以把這種能力往下傳遞。 DO 獲得了持久能力,就有點接近富血模型的想法了,他能夠處理一些業務,做持久然後調用引用對象的業務和持久方法 ( 從另外的角度看持久與業務其實是分不開的 ) 。這樣把業務封裝在了領域本身,更适于用領域對象出發的方式去思考問題。領域層的 façade 主要是為了 Transaction 管理和隐藏 DO 接口。這樣 DO 的業務方法都可以設定成 friendly ,僅互相間可見。 Façade 就放在 domain 包中,它負責給 DO 注入 persistence bean ,調用 DO 的接口,提供給 controller 一個 use case 級别的接口,同時它也代理 fetcher 的接口。

有了這個架構,實作起來也不複雜,要配置的 bean 很少(現在還沒有使用 spring 2.0 将 DO 配置在容器中)。設計就從 DO 出發,明确它的屬性和方法,讓 hibernate 自己生成資料庫表。

       這樣設計也算是一次嘗試吧,其中肯定有很多考慮不周的地方,需要不斷的讨論和改進。

繼續閱讀