17 February 2006

我朋友最近正在讀 POJOs in Action 這本書。Repository/DAO/Hibernate/JDBC 之間的關係搞的他一頭渾水,下面我嘗試就我所知的,提供一些解釋:

Repository 是 domain 中,有關 儲存 這種觀念的具現。當你在 model domain 時,你會觀察到有些物件在建立完成後,需要被留下來,並且 儲存在某個地方。然後下次要用時再把它取出,然後繼續工作。下面是物件的 life cycle 的流程:

   new object --> object working... --> persistent and store object 
   --> query stored object --> object continue working --> ....

當你觀察到這些行為後,你可以將這個觀念抽象化,並且設計一個專職的 物件來管理。在 Domain Driven Design 這本書中,作者命名這樣的物件為 Repository 。從上面的流程也可以看出,建立一個新的物件其實也算是物件生命週期的一環,所以 Repository 有時也會負責物件的建立。當然 如果建立的過程很複雜,可以採另一個 pattern: Factory 來輔助。

Repository 和 DAO 雖然同樣是處理資料,但是 Repository 著眼點和 DAO 並不一樣。DAO 只知道存取資料這種事,不會從物件的生命週期去思考。而物件的生命週期 和 business logic 是習習相關的,所以在設計上,Repository 是 domain 的一環,也會包含一些 business logic。比方說 AccountRepository 可能會 throw DuplicateAccountException 這種 business exception。如果是純 DAO 的話, 就不該寫這種東西了。

整理 DAO/Repository/Hibernate/JDBC 等之間的關係:

  • Pattern:
    • Repository -- 專職管理 Object 生命週期的物件。
    • DAO -- 專職處理資料的物件
  • Tools and Framework:
    • JDBC -- Java 處理 RDBMS 的工具
    • Hibernate -- Java 處理 Object 與 RDBMS mapping 的工具

Repository 和 DAO 都只是 pattern 的一種,可以應用在各種領域。 沒人規定 DAO 只能用在 JDBC,如果要處理 xml 資料,也可以套用 DAO 這個 pattern 來輔助。同理 Repository 也是一樣,跟 JDBC/Hibernate...這些工具一 點關係也沒有。再者 Design pattern 也跟 Java 也沒什麼關係,想在 C# 裡套用 Repository, DAO 也行。

把 Hibernate 和 Respository 綁在一起只是 POJOs in Action 作者的做法而已。 他覺得這兩個是完美的組合,所以他才寫書推廣他的理念。事實上也是如此,因為 Hibernate 提供很多方便管理 Object 生命週期的功能,所以寫起 Repository 變的很簡單。如果未來 Respository 真的很多人採用了,那麼 Hibernate 的功 勞可不小啊。

不過 Repository 這一詞在整個程式界裡不是很多人採用,有時候明明大家 寫的是 repository,卻也叫 DAO。所以大多數的時候只會看到 DAO 這個詞 。用 Repository 一詞的只有 Domain Driven Design 和 POJOs in Action 這兩本 書而已。

我個人是採用折衷的方式:我都管它們叫 DAO,而不是 Repository,一來 DAO 大家比較看的懂,二來 DAO 只要三個字母,比 Repository 短很多。 不過我的 DAO 也會兼差做些 Repository 的事就是了,但是比例很少,因為我不希望存取資料庫的程式碼混合 business logic,而且這樣 Unit Test 也不大好寫。


回響

可以用 Tag <I>、<B>,程式碼請用 <PRE>