J2EE分層設計是Java企業應用的最基本的設計思想。
從最常規的分層結構來說,系統層次從上到下依次為:
表現層:主要是客戶端的展示。
服務層:直接為客戶端提供的服務或功能。也是系統所能對外提供的功能。
領域層:系統內的領域活動。
DAO層:數據訪問對象,通過領域實體對象來操作數據庫。
其中有些指導原則:
1、上層總是依賴其下層,依賴關系不跨層。
2、表現成除外,同一層之間方法不允許相互調用。這是實際開發中一些開發者容易范的錯誤!如果真是同一層之間存在方法調用,需要注意,這些調用都是一些上層不可見方法,比如一些工具方法等。
3、一切從服務層出發,從系統需要提供的功能進行分析,確定Service接口中的方法。而不是從數據庫的表出發,創建DAO,再創Domain,然後Service,這實際上是對系統分層的誤解。
4、系統最核心的設計就是將系統中的實體劃分為領域模型。在此基礎上設計數據的DAO層,並將這些活動暴露給服務層,服務層的實現依賴於領域活動。
5、每個接口的職責范圍明確有界。
在我所做的系統中,常常看到一些糟糕的編碼:系統設計從表開始,一個表對應一個DAO,一個DAO對應一個domain,一個Domain對應一個Service,實際上Service的接口和DAO的接口基本上完全一樣!導致Service的接口方法超多!到了表現層,前台程序員在寫Action的時候,Action中反復的調用Service方法,代碼不堪入目。
正確的設計應該是,一個領域活動會聚合對應一個或一組DAO,來完成一個領域活動。而一個服務可能包含兩個領域活動,比如一個轉賬的業務,對應兩個領域活動。兩個帳戶的金額分別發生變化,需要操作一組領域活動,而每個活動需要操作很多表(調用多個DAO)。 事務的控制我們可以放到Service層。
目前,越來越多的架構師喜歡領域模型驅動設計,針對系統的領域模型建模,然後上層直接是Service,Service下面就是領域活動層Activity,從而去掉了DAO層,這樣做的優點是系統設計思路更清晰,目標更明確。可以避免上面所說的一個表對應一個DAO、Service的情況。
但缺點是當領域活動發生變化的時候,會引起領域活動層代碼的變化。並且,當要更換持久化框架或者技術時候,領域活動要重新實現。
但綜合考慮起來,這樣帶來的優點也很多,而實際上更換數據庫和持久化框架的情況很少,因此這樣的設計也是有其合理性一面的。這樣做實際上是將原來的DAO和Domain層合並為一個Activity.但上層的設計思路還是一致的。
其實Service層的設計也很講究,其中就是要控制Service的數量,從Service層往下,接口數量逐層增加。通常將一個模塊的服務都集中到一個Service中來處理。
每層中的每個接口都應該關注的是自己的那一塊,而不是吃著碗裡看著鍋裡,牛槽伸出個狗舌頭,最典型的例子就是一個DAO中胡亂操作別的表。這種凌亂的實現只會置項目經理與死地。也會為軟件的維護帶來很大代價。
筆者曾遇到這樣的團隊,缺乏對整個項目的整體設計,一個表一個DAO,對應一個Service,系統也不大,三四十張表,但是性能相當地下,經常down機。
最終發現,失敗不是開源框架和數據庫以及應用服務器和硬件配置的錯,根源在於拙劣的設計導致。
希望以後大家在做項目的時候能注意點。
原文出處:http://lavasoft.blog.51cto.com/62575/83974