楊慧 北京北大方正軟件技術(shù)學(xué)院
MVC模式在J2EE和.NET中的對(duì)比研究
楊慧 北京北大方正軟件技術(shù)學(xué)院
本文針對(duì)在多層分布式計(jì)算中,通過(guò)對(duì)MVC設(shè)計(jì)模式、J2EE及.NET的研究,系統(tǒng)探討了開發(fā)基于網(wǎng)絡(luò)的分布式計(jì)算工程(如企業(yè)級(jí)應(yīng)用系統(tǒng))的方法。
MODEL1;MODEL2;MVC設(shè)計(jì)模式;J2EE;.NET;EJB
本文以統(tǒng)計(jì)系統(tǒng)為例,針對(duì)統(tǒng)計(jì)系統(tǒng)高效靈活性、可維護(hù)性、可擴(kuò)展性、可復(fù)用性、易用性等需求,通過(guò)對(duì)多層分布式計(jì)算、MVC模式、J2EE及.NET的研究,系統(tǒng)探討了開發(fā)基于網(wǎng)絡(luò)的分布式計(jì)算工程(如企業(yè)級(jí)應(yīng)用系統(tǒng))的方法。
1.1 由傳統(tǒng)的MODEL1發(fā)展到MODEL2
JAVA WEB應(yīng)用的結(jié)構(gòu)經(jīng)歷了兩個(gè)階段,也就是從傳統(tǒng)的M O D E L 1發(fā)展到MODEL2。在MODEL1模式下,整個(gè)WEB應(yīng)用全部由JSP頁(yè)面組成,JSP頁(yè)面接收處理客戶端請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理后可以直接做出響應(yīng),還可以用少量的JAVABEAN來(lái)處理數(shù)據(jù)庫(kù)連接、數(shù)據(jù)庫(kù)訪問(wèn)等操作,在這種模式里JSP頁(yè)面身兼VIEW和CONTROLLER兩種角色,容易將控制邏輯和表現(xiàn)邏輯混雜在一起,使代碼的重用性降低,增加了應(yīng)用的擴(kuò)展性和維護(hù)的難度。由于這種模式的實(shí)現(xiàn)比較簡(jiǎn)單、局限性強(qiáng),適合開發(fā)小規(guī)模項(xiàng)目。
M O D E L 2也就是我們說(shuō)的M V C(MODEL_VIEW_CONTROL)架構(gòu)的設(shè)計(jì)模式是軟件設(shè)計(jì)的典型模式,它強(qiáng)制性的使應(yīng)用程序的輸入、處理和輸出分開。使用MVC應(yīng)用程序被分成三個(gè)核心部件:模型、視圖、控制器。在這種設(shè)計(jì)模式下,MODEL、VIEW和CONTROL三個(gè)部分各負(fù)責(zé)不同的功能,并將其劃分成不同功能的邏輯模塊,使模塊間的關(guān)聯(lián)最小化,因此,特別適用于基于網(wǎng)絡(luò)的分布式計(jì)算工程,如企業(yè)級(jí)應(yīng)用系統(tǒng)。下面我們來(lái)詳細(xì)認(rèn)識(shí)一下MVC模式的組成。
MODEL:模型,在MVC的三個(gè)部件中,模型擁有最多的處理任務(wù)。代表應(yīng)用數(shù)據(jù)和控制這些數(shù)據(jù)的商業(yè)邏輯,負(fù)責(zé)處理由控制器傳遞過(guò)來(lái)的對(duì)數(shù)據(jù)的訪問(wèn)請(qǐng)求,為視圖提供最終用以展現(xiàn)的數(shù)據(jù),為控制部分提供方便的接口。通過(guò)模型,視圖可以訪問(wèn)數(shù)據(jù),并根據(jù)客戶端的要求來(lái)顯示數(shù)據(jù)。被模型返回的數(shù)據(jù)是中立的,也就是說(shuō)模型與數(shù)據(jù)格式無(wú)關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)。由于應(yīng)用于模型的代碼只需寫一次就可以被多個(gè)視圖重用,所以減少了代碼的重復(fù)性。
VIEW:視圖,視圖是用戶看到并與之交互的界面,負(fù)責(zé)如何具體的展現(xiàn)模型的內(nèi)容。當(dāng)模型發(fā)生變化時(shí),視圖將負(fù)責(zé)保持界面的一致性,并同時(shí)改變顯示的數(shù)據(jù)。對(duì)老式的Web應(yīng)用程序來(lái)說(shuō),視圖就是由HTML元素組成的界面,在新式的Web應(yīng)用程序中,HTML依舊在視圖中扮演著重要的角色,但一些新的技術(shù)已層出不窮。如何處理應(yīng)用程序的界面變得越來(lái)越有挑戰(zhàn)性。MVC的好處之一是它能為你的應(yīng)用程序處理很多不同的視圖。視圖也負(fù)責(zé)將用戶的交互信息傳遞給控制部分。在視圖中其實(shí)沒(méi)有真正的處理發(fā)生,不管這些數(shù)據(jù)是聯(lián)機(jī)存儲(chǔ)的還是一個(gè)雇員列表,作為視圖來(lái)講,它只是作為一種輸出數(shù)據(jù)并允許用戶操縱的方式。
CONTROL:控制部分,處在視圖和模型之間,接受用戶的輸入并調(diào)用模型和視圖去完成用戶的需求。負(fù)責(zé)處理用戶請(qǐng)求和數(shù)據(jù)同步,是一系列接收用戶動(dòng)作(比如鼠標(biāo)和鍵盤的事件)的對(duì)象。結(jié)合模型和視圖,把客戶端的請(qǐng)求轉(zhuǎn)換成模型能夠理解并執(zhí)行的請(qǐng)求,并且根據(jù)請(qǐng)求以及執(zhí)行結(jié)果決定其后所要顯示的視圖。在傳統(tǒng)的圖形用戶界面,控制部分包括按鈕,菜單等等。在WEB應(yīng)用程序中,可以是對(duì)HTTP請(qǐng)求的GET或者POST方法。基于用戶的請(qǐng)求和模型的需要,控制部分負(fù)責(zé)選擇相應(yīng)的視圖將數(shù)據(jù)展現(xiàn)給用戶。
以上三者的關(guān)系在應(yīng)用中我們說(shuō)是相互關(guān)聯(lián)和控制的,程序利用三種模型的關(guān)系來(lái)更好的實(shí)現(xiàn)模塊的耦合。

圖1 M V C應(yīng)用程序中模型、視、控制器三部分的關(guān)系
綜上所述,在M O D E L 2架構(gòu)中,SERVLET作為前端控制器,負(fù)責(zé)接收客戶端發(fā)送的請(qǐng)求,在SERVLET中只包含控制邏輯和簡(jiǎn)單的前端處理;然后調(diào)用后端JAVABEAN來(lái)完成實(shí)際的邏輯處理;最后,轉(zhuǎn)發(fā)到相應(yīng)的JSP頁(yè)面處理顯示邏輯。我們從圖中可以看到,在MODEL2下JSP不再承擔(dān)控制器的責(zé)任,它僅僅是表現(xiàn)層角色,僅僅將結(jié)果呈現(xiàn)給用戶,JSP頁(yè)面的請(qǐng)求與SERVLET交互,而SERVLET負(fù)責(zé)與后臺(tái)的JAVABEAN通信,也就是說(shuō)MODEL由JAVABEAN充當(dāng),VIEW由JSP頁(yè)面充當(dāng),而CONTROL由SERVLET充當(dāng)。所以MVC更適合大規(guī)模軟件的開發(fā),但出增加了應(yīng)用開發(fā)的復(fù)雜程度。
1.2 MVC設(shè)計(jì)模式在軟件開發(fā)中的優(yōu)勢(shì)
MVC并不是JAVA語(yǔ)言所特有的設(shè)計(jì)思想,也并不是WEB應(yīng)用所特有的思想,它是所有面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言都應(yīng)該遵守的規(guī)范。
MVC給出了一個(gè)耦合松散的架構(gòu)。對(duì)于MVC分別對(duì)應(yīng)的三部分功能來(lái)講,用戶界面發(fā)生變動(dòng)的可能性最大,控制部分變動(dòng)次之,而業(yè)務(wù)邏輯相對(duì)是比較穩(wěn)定的。通過(guò)使視圖完全獨(dú)立于控制部分和模型,可以輕松替換前端客戶程序。將控制部分和模型分開可以在不影響模型的情況下改變控制器,也可以在不影響控制部分的情況下改變模型。所以采用這種設(shè)計(jì)模式,不論在哪一部分發(fā)生改變,都能夠以最小的代價(jià)使系統(tǒng)能夠平穩(wěn)過(guò)渡,不至于造成全局功能實(shí)現(xiàn)上的混亂,而且程序整體上結(jié)構(gòu)清晰,性能穩(wěn)定可靠,更易維護(hù),伸縮性好,易于擴(kuò)展、維護(hù)和代碼重用,更有利于在項(xiàng)目組內(nèi)按照成員各自的擅長(zhǎng)進(jìn)行分工,使三個(gè)部分可以并行開發(fā),加快項(xiàng)目進(jìn)度,簡(jiǎn)言之,以更快的速度開發(fā)更好的軟件。
從設(shè)計(jì)模式的角度來(lái)看,MVC思想非常類似于觀察者模式,但與觀察者模式存在少許差別:觀察者模式下觀察者和被觀察者可以是兩個(gè)互相對(duì)等的對(duì)象,但對(duì)于MVC思想而言,被觀察者往往只是單純數(shù)據(jù)體,而觀察者則是單純的視圖頁(yè)面。
基于組件的J2EE平臺(tái)提供了支持MVC設(shè)計(jì)模式很好的開發(fā)環(huán)境。模型可以通過(guò)EJB實(shí)現(xiàn);視圖可以通過(guò)HTML頁(yè)面、JSP頁(yè)面及功能強(qiáng)大的applet展示給用戶; 控制部分則是 servlet、Java Bean 或 session bean 類。其模塊間的通信協(xié)議采用RMI/IIOP,數(shù)據(jù)庫(kù)連接部分是JDBC,運(yùn)行環(huán)境是Java虛擬機(jī)(Java Virtual Machine),其中間語(yǔ)言是Java Byte Code。
模型部分,編寫業(yè)務(wù)邏輯時(shí),可以將完成這些功能的業(yè)務(wù)邏輯放置在EJB中,這樣,我們就可以將精力集中在解決關(guān)鍵的業(yè)務(wù)邏輯問(wèn)題上,而利用enterprise bean容器來(lái)支持低層服務(wù),如安全,線程管理,事務(wù)管理,狀態(tài)管理,遠(yuǎn)程數(shù)據(jù)訪問(wèn)等。將業(yè)務(wù)邏輯與低層系統(tǒng)邏輯分開使容器可以在運(yùn)行時(shí)創(chuàng)建和管理enterprise bean,而按照規(guī)范編寫的任何enterprise bean,都可以根據(jù)其在特定J2EE應(yīng)用程序中的使用情況來(lái)對(duì)其事務(wù)管理或安全屬性進(jìn)行配置,并可以輕松的部署到任何一個(gè)符合規(guī)范的容器中,也就是說(shuō),不必改變代碼,也不必重新編譯enterprise bean,即可實(shí)現(xiàn)組件重用。Enterprise bean 由接口和類組成。客戶端程序通過(guò)enterprise bean的home接口和遠(yuǎn)程接口來(lái)訪問(wèn)enterprise bean的方法。Home 接口提供了創(chuàng)建、刪除和定位enterprise bean 的方法,而遠(yuǎn)程接口則提供了實(shí)現(xiàn)業(yè)務(wù)邏輯的方法。在部署時(shí),容器由這些接口來(lái)創(chuàng)建類,使客戶能夠創(chuàng)建、刪除、定位或調(diào)用位于enterprise bean 上的業(yè)務(wù)邏輯方法。Enterprise beans有兩種:session bean和entity bean。前者代表與客戶程序的一個(gè)短暫的會(huì)話,也可執(zhí)行數(shù)據(jù)庫(kù)讀寫操作,其內(nèi)容包含會(huì)話狀態(tài),而且是短暫的。如果服務(wù)器或者客戶程序崩潰,該session bean 就會(huì)丟失。Session beans 可以是有狀態(tài)的,也可以是無(wú)狀態(tài)的。一個(gè)有狀態(tài)的session b e a n包含客戶程序的會(huì)話狀態(tài)。有狀態(tài)session bean并不代表在一個(gè)持久數(shù)據(jù)存儲(chǔ)中的數(shù)據(jù),但是它可以代表客戶程序訪問(wèn)和更新數(shù)據(jù)。無(wú)狀態(tài)session bean沒(méi)有用于某個(gè)特定客戶程序的任何狀態(tài)信息,因此通常用于提供不保持任何特定狀態(tài)的服務(wù)器端行為。entity bean代表一個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)及作用于該數(shù)據(jù)的方法。在關(guān)系型數(shù)據(jù)庫(kù)中,每行數(shù)據(jù)都由一個(gè)bean 來(lái)代表。entity beans 是事務(wù)性的,并且是長(zhǎng)壽命的,只要數(shù)據(jù)留在數(shù)據(jù)庫(kù)中,entity bean 就存在,因此可以被很容易地用于關(guān)系型數(shù)據(jù)庫(kù),而不僅限于對(duì)象數(shù)據(jù)庫(kù)。
視圖部分,如果應(yīng)用的是HTML頁(yè)面,略懂計(jì)算機(jī)的人就可以更新它。如果使用的是JSP 頁(yè)面,將控制器的代碼放到一個(gè)Java Bean 或session bean類中,或使用動(dòng)作標(biāo)記(action tags),這樣,JSP 頁(yè)面就可以僅包含JSP 代碼。視圖部分也包括applet和各種腳本語(yǔ)言,功能強(qiáng)大而且界面友好易用。
控制部分,通常是在servlet中實(shí)現(xiàn)的。Servlet是一種獨(dú)立于平臺(tái)和協(xié)議的服務(wù)器端的Java應(yīng)用程序,可以生成動(dòng)態(tài)的Web頁(yè)面。與傳統(tǒng)的從命令行啟動(dòng)的Java應(yīng)用程序不同,Servlet由Web服務(wù)器進(jìn)行加載,該Web服務(wù)器必須包含支持Servlet的Java虛擬機(jī)。盡管JSP文件最終也將編譯成servlet,但從整個(gè)系統(tǒng)的角度來(lái)講,用servlet實(shí)現(xiàn)控制部分將使系統(tǒng)結(jié)構(gòu)清晰,各個(gè)部分銜接會(huì)更好。
綜合我們對(duì)J2EE應(yīng)用的了解,我們知道對(duì)于大型軟件系統(tǒng)開發(fā),采用J2EE應(yīng)用架構(gòu)則有很大的優(yōu)勢(shì)。
.NET同樣提供了出色的實(shí)現(xiàn)這種設(shè)計(jì)模式的規(guī)范和集成開發(fā)環(huán)境,以asp.net為例,我們可以在.ASPX文件中開發(fā)用戶接口來(lái)實(shí)現(xiàn)視圖,控制部分在邏輯功能代碼(code-behind)文件(如*.aspx.vb或者*.aspx.cs)中實(shí)現(xiàn),模型可以通過(guò)程序代碼實(shí)現(xiàn)(如*.cs),程序代碼最終都打包成COM+組件,相比原來(lái)的ASP解釋執(zhí)行,大大提升了性能。其模塊間的通信協(xié)議通常是DCOM或者SOAP,數(shù)據(jù)庫(kù)連接部分采用ADO.NET,運(yùn)行環(huán)境是Common Language Runtime,其中間語(yǔ)言是MSIL。
將數(shù)據(jù)展現(xiàn)從控制部分中分離出來(lái)提高了代碼的重用性,而將模型從對(duì)其操作的控制部分分離出來(lái)可以設(shè)計(jì)一個(gè)與后臺(tái)存儲(chǔ)數(shù)據(jù)無(wú)關(guān)的系統(tǒng),也就是說(shuō),提供給模型的數(shù)據(jù)是存儲(chǔ)在SQL Server或是Oracle數(shù)據(jù)庫(kù)中,還是存儲(chǔ)在一組XML文檔中,對(duì)于基于MVC設(shè)計(jì)模式的系統(tǒng)將是透明的。
性能方面,盡管從控制部分和視圖中訪問(wèn)模型是獨(dú)立于具體數(shù)據(jù)庫(kù)的,但并不意味著模型不能被優(yōu)化。因?yàn)锳DO Data Set不關(guān)心數(shù)據(jù)源,通過(guò)采用數(shù)據(jù)庫(kù)專有的優(yōu)點(diǎn)不用打破這種模式就可以提高系統(tǒng)性能。例如,相比在控制部分代碼文件中使用嵌入的SQL Select語(yǔ)句,我們可以使用存儲(chǔ)過(guò)程根據(jù)其參數(shù)返回?cái)?shù)值,效果會(huì)好很多,因?yàn)榇鎯?chǔ)過(guò)程不僅僅是被數(shù)據(jù)庫(kù)中預(yù)編譯好的,它們還有一個(gè)預(yù)先確定的執(zhí)行路徑,所以其執(zhí)行得更快,效率更高。
模型在數(shù)據(jù)訪問(wèn)時(shí),我們可將所有的代碼合并在一個(gè)單獨(dú)的數(shù)據(jù)訪問(wèn)對(duì)象中,由它來(lái)完成該系統(tǒng)所有的數(shù)據(jù)訪問(wèn)。集中的數(shù)據(jù)訪問(wèn)提升了代碼重用性,更重要的是,通過(guò)使用實(shí)際容量設(shè)置連接可以保證應(yīng)用程序使用連接池,從而提高效率。
控制器部分,.NET通常直接地請(qǐng)求服務(wù)。取代身為子控制器的一個(gè)服務(wù),它是進(jìn)入ASP.NET應(yīng)用程序的主要切入點(diǎn)。
以MVC設(shè)計(jì)模式為出發(fā)點(diǎn),結(jié)合J2EE和.NET的相應(yīng)特點(diǎn),我們總結(jié)出如表1所示:

表1 MVC在J2EE和.NET中的實(shí)現(xiàn)方法
綜上所述,可以得出結(jié)論:
通過(guò)對(duì)多層分布式計(jì)算,結(jié)合MVC的設(shè)計(jì)思想,充分利用J2EE架構(gòu)的優(yōu)勢(shì),使統(tǒng)計(jì)系統(tǒng)結(jié)構(gòu)清晰,穩(wěn)定高效,易維護(hù),易擴(kuò)展;滿足了統(tǒng)計(jì)系統(tǒng)高效靈活性、可維護(hù)性、可擴(kuò)展性、可復(fù)用性、易用性等需求。在開發(fā)基于網(wǎng)絡(luò)的分布式計(jì)算工程(如企業(yè)級(jí)應(yīng)用系統(tǒng))的時(shí)候,充分考慮到了系統(tǒng)將來(lái)的可擴(kuò)充性以及可移植性,以便系統(tǒng)的進(jìn)一步完善。
10.3969/j.issn.1001-8972.2011.24.041
楊慧,女,副教授,清華大學(xué)在職研究生,現(xiàn)在北京北大方正軟件技術(shù)學(xué)院擔(dān)任教師。