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