10 July 2005

最近又看了一本 Pro Spring,喔~ 裡面的第十一章 (Designing and implementating spring-based applications) 真是太棒囉!很多建議都相當的實用,解決了許多困惑我很久的疑問。這樣子差不多可以理出個頭緒了

o J2EE without EJB

採用 Struts + Hibernate +Spring 三個 framework 開發專案,每個framework都提供較 j2ee 更簡單、更快速、更open的實作。

o 整個架構分為四層

  • Presentation Layer - 處理使用者的互動,即人機界面相關的部份,Struts Action 為主角
  • Application Service Layer - Business Service Facade。Struts 的 Action 下面就是這一層了,此層的各個 method 都直接對應使用者的需求,另外也提供其他 middle-ware 的服務,像是 transaction / mail / remoting... 等等。這一層由 Spring 控管。
  • Domain Layer - 這一層充滿了一堆 entity 與 value object,每個物件都對應 Domain 所面對的問題。這一層的物件不歸任何人管,是完完全全的 POJO。
  • Persistence Layer - 負責 Domain 物件的儲存、修改及查詢. (即管理物件的中間生命週期),這裡是由 Hibernate 在背後 "透明" 的支援 Domain 的物件。

各層的邊界畫分起來就像這樣:
Struts Action <-> Spring Service <-> Domain Layer <-> DAO

o 保持 domain layer 乾淨

  • 進入 domain layer 前,先將 "資料" 轉換為 domain object,無論是從 database 來的或是使用者輸入的。
  • domain object 不應與任何 framework, container, context, enviroment... etc 等相關。所有存在於Domain Layer 的物件僅僅是互相連結的 POJO。
  • Domain Layer 並沒有像其他層級一樣,有一個 Class (Action or DAO... etc) 可以標示出它的邊界。不過大致上都是在 Service Facade 裡操作就是了,其他的 Layer 碰到 Domain 物件時,多半都是只呼叫它的 getter 而已。
  • 此層無任何 persistence 的相關工具。也就是說你的那些 Domain 物件,是看不到那些 DAO 的,是 Service 派遣 DAO 來服務那些 Domain 物件,而不是 Domain 物件主動去找 DAO 做東做西的。另外,老實說所謂的 HibernateUtil 在某種程度上算是 Anti-pattern 了。這個全域皆可存取的 persistence 工具真是太可怕了,如果控制不好,真的是到處流竄。小的系統當然是可以用的很爽,但稍微大一點的就受不了了!
  • 呈上點,稍微大一點的系統指的是: 如果 Appilcation 需要 Domain Layer 時,這個 Appilcation 已經算是大的,夠複雜了。如果 Application 很單純,不到十個 Table 或者是跟本是 Data centric,那犯不著花工夫替問題建立一層 Domain和 DAO,直接在 Facade 那呼叫 HibernateUtil 就搞定了,甚至不用 Hibernate 會更簡單、更快。
  • 依照 Domain Driven Design 一書作者(Eric Evans)的說法,他也認為 Domain 不應該涵蓋到 DAO 的... 從另一方面佐證,根據 TDD 的理論 -- 難 test 的 code 就是含有 bad smell -- 最近實務上的經驗發現如果 Domain 物件包含 DAO,Unit Test 真是難寫斃了,就算硬寫出來也不叫 "Unit" 了!
  • Spring 的 sandbox 裡有提供實驗性的 D.I. 工具,讓你可以將 Spring 管理的物件 inject 到 Hibernate 的 Persistence Object。相關討論。用這個就可以將 DAO inject 到 Domain 物件裡啦。不過由於 domain object 多半數量龐大,inject 到這麼多的物件會對 performance 影響多少... 還是個未知數。另外這種做法會漸漸讓 Spring 入侵到 POJO 裡了... 個人不大喜歡... 暫時先觀望觀望...
  • 小心違反 Law of Demeter... 待續
哇咧,怎麼才寫到 Domain Layer 就快12點了....

(12:18pm 時修改過,剛誤解 Eric Evans 的見解了,呼~~ 鬆了一口氣)


回響

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