網址在這里:http://forum.javaeye.com/viewtopic.php?t=627&postdays=0&postorder=asc&start=0
說實在的,這是很理想化的設計方案,真的,我的想法也一樣,之所以是這樣,主要是因為我看了一本Struts的書,是奧來理出版的,里面就是這樣的一個概念,雖然那本書里并沒有嚴格按照這樣的思路來做.不過也可以看出這是很完美的,但也是不可取的方案.
不可取的地方在哪里?性能問題,主要是從Service層上來的實體都可進行數據轉換(DT),生成View層的DTO,單個實體是一次轉換,多個實體,比如set,iterator等,就要n次轉化,而這些僅僅是為了使視圖層和Service層分離,這是不明智的.
不過這樣的模式的出現也是有原因的.因為應用這個Service層可能會有多樣的客戶端,在適應多種客戶端的就要用到這些東西,比如客戶端是一個Swing GUI程序?那么他需要的是一個序列化的數據包,而這個數據庫僅僅列出的就是健值對,為了設計簡單,這個客戶端就不應該知道服務器端的類以及類的聯系,它僅僅依賴于Service層提攻的DTO,那么就要用到DTO,OK,現在明白robin的設計想法是相當合理,而且重用性很高的.這是大型J2EE程序所常用的方法.
但對于專用于Web而永遠不打算有其它客戶端的中小Web程序來言,上面的方法已經有些不合時宜了,可以說沒有必要死搬了.也就是說設計應該有所退化,至于退化成什么樣子,是很讓人覺得為難的.我現在的思想是:所有實體對象從最頂層的視圖層到最底層的持久層,都是可以共用的,這樣就不存在DT的問題,那么中間過程是怎么樣的呢?
我的分法是這樣:
視圖層
-----
控制層
-----
服務接口層
-----
業務邏輯層
-----
持久層
-----
數據庫層
穿梭于其中的數據杻帶是PO,也可以說它是VO.這些層從上往下依賴,比如說持久層依賴于數據庫層,如果數庫的設計有所變化,必然會導至持久層設計發生變化,而持久層也因此影響業務邏輯層,從而產生骨牌效應.雖然這樣的設計是不好的,但是誰能夠解決這樣的事情呢?數據庫這樣最底層最核心的東西都改變了,這必然會影響整個程序的行為,比如說數據庫要求多加一個計錄評分級別的功能,可是原來的程序里沒有這樣的功能,而且所有的調用接口都沒有寫到這方面的功能,那么不就是整個程序只要和這個功能有關的程序文件都要進行修改,這是不可避免的(如果可以避免,請告訴我方法,小弟永生記住您的大恩).
為什么要分多一個服務接口層?很簡單,主要是把業務邏輯脫離特定的Web框架,不論是在Struts、Webwork、JSF,他們都可正常運行,當然你也可以不要這一層,把業務邏輯寫進Action,這樣從而把程序死死綁定到了某個Web Framework,這樣的好處是,程序的性能有很小的提高,不過苦果是,某一天要改成其它的Web framework呢?我建議的方案是加多一個服務接口層,這樣Action主要的任務就是從接口層取得數據轉到視圖層去顯示,這樣Action的重任就很清楚了,它只是一個控制器而已(笑話,那么這些自稱MVC的框架,啟不只是VC而已?哈…………)
那么什么是業務邏輯層呢?因為程序并不只是涉及數據庫操作,而且常會伴隨一些文件操作,而這些都是對一實體的一次單元操作,而且是可重用的操作.業務邏輯層就是這樣的單元操作接口,他調用持久層,更確切的說是DAO,得到PO,但后進行相關的操作。
注意,這里的持久層不是具體到Hibernate的這些ORM,而只是DAO,具體的ORM由具體的DAO實現。
呵。。。從上面這句話,也許你也會想問一個問題,具體的DAO?對,就是具體的DAO。這里就運用的面向接口編程的思想,層與層之間調用的只是接口而已,每一層都有特定的實現,而這些特定的實現是可插拔的,而且不會影響原程序的運行。你可以用Factory模式生成具體的DAO bean,呵…………這是一個痛苦的過程,而且Factory這樣與程序邏輯無關的東西竟然一躍而上進入了我們的代碼,這不是一個好的方法,我們可以用一種IoC框架,Spring就是一個極好的東西,注入我們想要的DAO bean,這樣我們寫代碼就可以專心對接口編程了,我們就沒有必要擔心什么Factory了,呵……
那么實體呢?他能接口化嗎?從我現在的所掌握的知識來看,他是不可接口化的,他是數據的載體,也是一些常規操作的載體,也正是因為這樣,他是極其重要也是極其簡單的,所以,他不用接口化。
好了,終于理清這半年來所思考的東西了,大至上我已經明白怎樣去合理的規范化設計一個程序,現在剩下的只是挑選合適的應用框架,然后做第一個Java Web開發。汗,直到現在我都還沒有真正開發過Java Web程序呢,呵…………