劉萍芬
摘要:基于B/S的軟件開(kāi)發(fā)需要一種科學(xué)的軟件開(kāi)發(fā)模式,MVC模式的設(shè)計(jì)思想為軟件的健壯性、可維護(hù)性和可擴(kuò)展性提供了有力的支持。文章介紹了MVC模式的體系結(jié)構(gòu)及功能,給出了多界面控制的設(shè)計(jì)與實(shí)現(xiàn),使用MVC模式開(kāi)發(fā)軟件充分體現(xiàn)了該模式的優(yōu)點(diǎn),增加了項(xiàng)目開(kāi)發(fā)的效率和復(fù)用性。
關(guān)鍵詞:MVC設(shè)計(jì)模式;多界面;XML
中圖分類(lèi)號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2013)09-2227-04
MVC(Model-View-Controler,模型-視圖-控制器)是Xeror PARC 在八十年代為編程語(yǔ)言Smalltalk-80所發(fā)明的一種軟件設(shè)計(jì)模式[1,2],至今已被廣泛使用,是一種劃分系統(tǒng)功能的方法,其為開(kāi)發(fā)交互式應(yīng)用系統(tǒng)提供了一個(gè)優(yōu)秀的設(shè)計(jì)模式,受到越來(lái)越多開(kāi)發(fā)者的歡迎。MVC模式三維目的是增加代碼的重用率,減少數(shù)據(jù)表達(dá)、數(shù)據(jù)描述和應(yīng)用操作的耦合度,同時(shí)也使得軟件可維護(hù)性、可修復(fù)性、可擴(kuò)展性、靈活性以及封裝性得以提高。
1 MVC模式體系結(jié)構(gòu)及功能分析
MVC把一個(gè)應(yīng)用的輸入、處理、輸出流程按照Model、View、Controller的方式進(jìn)行分離,這樣一個(gè)應(yīng)用被分成三個(gè)層,即模型層、視圖層、控制層[3]。
模式的核心就是做到三層甚至多層的松散耦合,是一種面向動(dòng)態(tài)內(nèi)容的實(shí)現(xiàn)方式。在MVC模式中,應(yīng)用程序被強(qiáng)制分成三個(gè)核心部件:模型(Model)、視圖(View)、控制器(Controller)。它們各自處理自己的任務(wù)。其模式結(jié)構(gòu)如圖1所示。
視圖是實(shí)現(xiàn)模塊的外觀,它是應(yīng)用程序的外在表現(xiàn)。它可以訪問(wèn)模型的數(shù)據(jù),但不能改變這些數(shù)據(jù),也不了解模型的情況,同時(shí)也不了解控制器的情況。當(dāng)模型發(fā)生改變時(shí),視圖會(huì)得到通知。一個(gè)模型可以由多個(gè)視圖,而一個(gè)視圖理論上可以同不同的模型關(guān)聯(lián)起來(lái)。
模型包含了應(yīng)用程序的核心,它封裝了應(yīng)用程序的數(shù)據(jù)結(jié)構(gòu)和事物邏輯,集中體現(xiàn)了應(yīng)用程序的狀態(tài)。它能夠處理部分的事物邏輯和數(shù)據(jù)結(jié)構(gòu),能夠與數(shù)據(jù)庫(kù)和文件系統(tǒng)進(jìn)行交互,承擔(dān)維護(hù)應(yīng)用程序的責(zé)任。
控制器封裝的是外界作用于模型的操作。通常,這些操作會(huì)轉(zhuǎn)發(fā)到模型上,并調(diào)用模型中相應(yīng)的一個(gè)或多個(gè)方法。一般控制器在模型視圖之間起到了溝通的作用,處理用戶在視圖上的輸入,并轉(zhuǎn)發(fā)給模型處理。這樣模型和視圖兩者之間可以做松散耦合,甚至可以彼此不知道對(duì)方,而由控制器連接起這兩個(gè)部分。
2 多界面控制的設(shè)計(jì)
2.1 客戶端視圖組件設(shè)計(jì)
PB,Dephi等客戶端通過(guò)本地的Dll與服務(wù)器端進(jìn)行數(shù)據(jù)交互,Dll設(shè)計(jì)的好壞直接影響客戶端的處理方式和數(shù)據(jù)格式的轉(zhuǎn)化處理。Dll設(shè)計(jì)應(yīng)該提供盡可能多的接口以便對(duì)盡可能多的視圖組件的數(shù)據(jù)進(jìn)行封裝。
通過(guò)對(duì)PB和Dephi的視圖組件的研究發(fā)現(xiàn),針對(duì)每個(gè)視圖組件封裝一個(gè)函數(shù)不太現(xiàn)實(shí),而且不利于后面的擴(kuò)展。新的組件加進(jìn)來(lái)必須提供新的處理轉(zhuǎn)化函數(shù)。因?yàn)槊總€(gè)視圖組件都有數(shù)據(jù)抽取的功能,可以把對(duì)組件的封裝處理轉(zhuǎn)化為對(duì)數(shù)據(jù)的封裝處理。
輸入規(guī)范中分為信封頭和信封尾,在頭信息中包含用戶登陸的用戶名、密碼、用戶登陸會(huì)話標(biāo)識(shí)和調(diào)用的EJB組件的標(biāo)識(shí)名等。在信封體中包含兩種請(qǐng)求數(shù)據(jù)類(lèi)型:?jiǎn)螀?shù)數(shù)據(jù)和參數(shù)集合。
輸入規(guī)范中同樣也包含信息頭和信息體。信息頭包含用戶登陸會(huì)話對(duì)象標(biāo)識(shí)。信息體中也包含兩個(gè)返回格式:?jiǎn)蝹€(gè)返回結(jié)果和結(jié)果集。
出錯(cuò)規(guī)范也分為信息頭和信息體,信息頭中和輸出規(guī)范一樣,包含用戶的登陸會(huì)話對(duì)象標(biāo)識(shí)。信息體中包含出錯(cuò)的代碼標(biāo)識(shí)和錯(cuò)誤描述信息。
把對(duì)數(shù)據(jù)的處理分為輸入數(shù)據(jù),輸出數(shù)據(jù)和出錯(cuò)數(shù)據(jù),對(duì)輸入數(shù)據(jù)分為單數(shù)據(jù)參數(shù)輸入和參數(shù)集輸入,對(duì)輸出數(shù)據(jù)也做同樣處理,分為單結(jié)果輸出和多結(jié)果集輸出。
2.2 服務(wù)器端控制組件設(shè)計(jì)
服務(wù)器端的設(shè)計(jì)主要包括控制層和模型層的設(shè)計(jì),控制層中主要為控制組件的設(shè)計(jì),模型層的設(shè)計(jì)主要為業(yè)務(wù)組件的設(shè)計(jì)和持久層的設(shè)計(jì)。博弈控制組件的設(shè)計(jì)是服務(wù)器端設(shè)計(jì)的核心,控制組件中包括格式轉(zhuǎn)化轉(zhuǎn)發(fā)器、數(shù)據(jù)格式轉(zhuǎn)化組件和業(yè)務(wù)組件的調(diào)用接口。
格式轉(zhuǎn)化轉(zhuǎn)發(fā)器(也稱(chēng)集中控制器)根據(jù)客戶端的請(qǐng)求頭信息判斷客戶端的類(lèi)型,如果請(qǐng)求頭信息的headFormat字段值為xml,根據(jù)format.properties配置文件信息轉(zhuǎn)發(fā)給XMLEvenlopConvert數(shù)據(jù)格式轉(zhuǎn)化器,如果請(qǐng)求頭信息中的heafFormat的值為map,則根據(jù)配置文件轉(zhuǎn)發(fā)給MapEvenlopConvert數(shù)據(jù)格式轉(zhuǎn)化器,如果是其他取值,則根據(jù)配置文件信息轉(zhuǎn)發(fā)給對(duì)應(yīng)的數(shù)據(jù)格式轉(zhuǎn)化器,這樣設(shè)計(jì)的好處是容易擴(kuò)展新的數(shù)據(jù)交換協(xié)議和添加新的數(shù)據(jù)格式轉(zhuǎn)化器,而不需要更改程序的代碼。同樣,當(dāng)中間層處理完后,把結(jié)果返回給數(shù)據(jù)格式轉(zhuǎn)化轉(zhuǎn)發(fā)器,轉(zhuǎn)發(fā)器根據(jù)配置文件信息轉(zhuǎn)發(fā)給對(duì)應(yīng)的數(shù)據(jù)格式轉(zhuǎn)化器,轉(zhuǎn)化器把結(jié)果轉(zhuǎn)化成客戶端需要的格式返回給客戶端。當(dāng)前系統(tǒng)中只用到兩種格式,xml格式為PB,Dephi客戶端發(fā)送的數(shù)據(jù)格式,map為瀏覽器發(fā)送的請(qǐng)求對(duì)象數(shù)據(jù)封裝格式。格式轉(zhuǎn)化轉(zhuǎn)發(fā)器在系統(tǒng)中充當(dāng)集中控制器的角色。如圖2所示。
數(shù)據(jù)格式轉(zhuǎn)化組件主要是對(duì)客戶端傳輸進(jìn)來(lái)的數(shù)據(jù)格式轉(zhuǎn)化為中間層處理的統(tǒng)一的數(shù)據(jù)格式,同時(shí)把中間層處理返回的數(shù)據(jù)格式轉(zhuǎn)化為客戶端需要的格式。
其中RequestEvenlop是傳輸給中間層的數(shù)據(jù)對(duì)象,而ResponseEvenlop是中間層處理后返回結(jié)果的數(shù)據(jù)對(duì)象。
數(shù)據(jù)格式轉(zhuǎn)化器必須提供可以把客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)轉(zhuǎn)化成RequestEvenlop數(shù)據(jù)結(jié)構(gòu),同時(shí)能夠把中間層的結(jié)果ResponseEvenlop轉(zhuǎn)化為客戶端需要的格式,數(shù)據(jù)格式轉(zhuǎn)化器接口的類(lèi)圖如圖3所示。
其他的數(shù)據(jù)格式轉(zhuǎn)化器必須實(shí)現(xiàn)該接口并根據(jù)客戶端的數(shù)據(jù)格式實(shí)現(xiàn)convertToEvenlop和convertFromEvenlop方法,圖4為XMLEvenlopConvert和MapEvenlopConvert實(shí)現(xiàn)BaseEvenlopConvert的類(lèi)圖。
控制組件根據(jù)xml的配置信息調(diào)用相應(yīng)的業(yè)務(wù)組件,通過(guò)工廠方法獲取業(yè)務(wù)組件實(shí)現(xiàn),然后調(diào)用業(yè)務(wù)組件中相應(yīng)的業(yè)務(wù)方法。
3 多界面控制的實(shí)現(xiàn)
3.1 客戶端Dll實(shí)現(xiàn)
客戶端的Dll主要是根據(jù)視圖組件的數(shù)據(jù)構(gòu)造符合系統(tǒng)SOAP XML規(guī)范的數(shù)據(jù)流。
Dll的實(shí)現(xiàn)主要是根據(jù)LdjSoap的接口實(shí)現(xiàn)對(duì)應(yīng)的函數(shù),主要實(shí)現(xiàn)代碼如下,其中引用到公用的Apache xml解析庫(kù)Xercesc:
3.2 服務(wù)器端控制器實(shí)現(xiàn)
1)轉(zhuǎn)發(fā)器主要實(shí)現(xiàn)
轉(zhuǎn)發(fā)器通過(guò)讀取配置文件來(lái)獲取數(shù)據(jù)格式轉(zhuǎn)化器,通過(guò)把請(qǐng)求數(shù)據(jù)或者返回結(jié)果給對(duì)應(yīng)的數(shù)據(jù)格式轉(zhuǎn)化器轉(zhuǎn)化成期望的數(shù)據(jù)格式,并調(diào)用對(duì)應(yīng)的請(qǐng)求處理器進(jìn)行業(yè)務(wù)處理。
通過(guò)把format.properties文件放到classpath路徑下,F(xiàn)ormatRedirector讀取format.properties文件并緩存到靜態(tài)變量formatPro中:
FormatRedirector根據(jù)從http請(qǐng)求對(duì)象中讀取的頭信息和流數(shù)據(jù)信息獲取對(duì)應(yīng)的數(shù)據(jù)格式轉(zhuǎn)化器進(jìn)行轉(zhuǎn)化處理:
2)數(shù)據(jù)格式轉(zhuǎn)化器主要實(shí)現(xiàn)
格式轉(zhuǎn)化器是服務(wù)器端實(shí)現(xiàn)的重點(diǎn),它把各種不同的數(shù)據(jù)請(qǐng)求對(duì)象轉(zhuǎn)化成業(yè)務(wù)組件需要的數(shù)據(jù)結(jié)構(gòu)RequestEvenlop,同時(shí)把業(yè)務(wù)組件返回的ResponseEvenlop數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化成客戶端需要的數(shù)據(jù)形式,如xml等。
本模塊中的所有處理結(jié)構(gòu)都是以XML形式返回給客戶端,PB等客戶端通過(guò)dll解析獲取,瀏覽器客戶端通過(guò)JS調(diào)用DOM對(duì)象處理獲取。
把ResponseEvenlop轉(zhuǎn)化成XML文本形式相對(duì)比較簡(jiǎn)單,下面實(shí)現(xiàn)如何把xml等對(duì)象轉(zhuǎn)化成RequestEvenlop數(shù)據(jù)結(jié)構(gòu)。
主要用到兩種轉(zhuǎn)化器XMLEvenlopConvert和MapEvenlopConvert。
MapEvenlopConvert對(duì)http請(qǐng)求對(duì)象進(jìn)行數(shù)據(jù)格式轉(zhuǎn)化,根據(jù)RequestEvenlop結(jié)構(gòu)特點(diǎn),很容易的從HttpServletRequest獲取到請(qǐng)求數(shù)據(jù):
Map dataMap=httpServletRequest.getParameterMap(); //獲取請(qǐng)求數(shù)據(jù)的名-值對(duì)。
之后可以直接把dataMap對(duì)象設(shè)置為RequestEvenlop的Body。
XMLEvenlopConvert把客戶端傳過(guò)來(lái)的xml文本格式轉(zhuǎn)化成RequestEvenlop數(shù)據(jù)結(jié)構(gòu)。
客戶端傳過(guò)來(lái)的Soap xml信息主要包括文檔頭信息和體信息。頭信息主要包括用戶名、密碼、功能點(diǎn)等;體信息是主要的業(yè)務(wù)數(shù)據(jù)。系統(tǒng)通過(guò)HeadParser把頭信息解析到RequestEvenlopHead,主要代碼如下:
系統(tǒng)通過(guò)注冊(cè)一序列反序列化器來(lái)實(shí)現(xiàn)對(duì)信息體的解析。不同的塊結(jié)構(gòu)用不同的反序列化器解析,系統(tǒng)提供有StringDeserializer, VectorDeserializer, HashMapDeserializer實(shí)現(xiàn)對(duì)普通參數(shù)、參數(shù)集合和行記錄集合的解析處理。
通過(guò)QnameMapping注冊(cè)已有的解析器種類(lèi),每種類(lèi)型的解析器都繼承Deserializer接口并提供對(duì)應(yīng)的實(shí)現(xiàn)方法(系統(tǒng)通過(guò)提供一個(gè)Deserializer的默認(rèn)實(shí)現(xiàn)DeserializerImpl,其他的類(lèi)型擴(kuò)展它實(shí)現(xiàn)):
SOAPHandler是一個(gè)SAX XML事件觸發(fā)解析的默認(rèn)實(shí)現(xiàn),通過(guò)SAX可對(duì)xml的不同元素進(jìn)行解析。DeserializerImpl擴(kuò)展SOAPHandler實(shí)現(xiàn)事件觸發(fā)解析功能。系統(tǒng)StringDeserializer主要是對(duì)Soap xml規(guī)范中的para元素解析,的實(shí)現(xiàn)如下:
系統(tǒng)的整個(gè)解析動(dòng)作通過(guò)DeserializationContext(實(shí)際上是通過(guò)DeserializationContextImpl)觸發(fā),XMLEvenlopConvert通過(guò)DeserializationContext的deserialize方法把xml數(shù)據(jù)流作為參數(shù)傳進(jìn)去,通過(guò)getValue()獲取解析后的RequestEvenlop的信息體。
4 結(jié)論
由上文可以看出,使用MVC模式開(kāi)發(fā)軟件充分體現(xiàn)了該模式的優(yōu)點(diǎn),增加了項(xiàng)目開(kāi)發(fā)的效率和復(fù)用性。MVC的優(yōu)點(diǎn)表現(xiàn)在以下幾個(gè)方面:
1) 可以為一個(gè)模型在運(yùn)行時(shí)同時(shí)建立和使用多個(gè)視圖。變化-傳播機(jī)制可以確保所有相關(guān)的視圖及時(shí)得到模型數(shù)據(jù)變化,從而使所有關(guān)聯(lián)的視圖和控制器做到行為同步。
2) 視圖與控制器的可接插性,允許更換視圖和控制器對(duì)象,而且可以根據(jù)需求動(dòng)態(tài)的打開(kāi)或關(guān)閉、甚至在運(yùn)行期間進(jìn)行對(duì)象替換。
3) 模型的可移植性。因?yàn)槟P褪仟?dú)立于視圖的,所以可以把一個(gè)模型獨(dú)立地移植到新的平臺(tái)工作。需要做的只是在新平臺(tái)上對(duì)視圖和控制器進(jìn)行新的修改。
4) 潛在的框架結(jié)構(gòu)??梢曰诖四P徒?yīng)用程序框架,不僅僅是用在設(shè)計(jì)界面的設(shè)計(jì)中。
參考文獻(xiàn):
[1] Leff A,Rayfield J T.Web-Application Development Using the Model/View/Controller Design Pattern[C].Fifth IEEE International Enterprise Distributed Object Computing Conference,September,2O01.
[2] 任中方,張華.MVC模式研究的綜述[J].計(jì)算機(jī)應(yīng)用研究,2004,21(10):1-4.
[3] Bergsten H.JSP設(shè)計(jì)[M].3版.北京:中國(guó)電力出版社,2004.
[4] 周必水,倪慧莉.簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議SOAP的研究與分析[J].微電子學(xué)與計(jì)算機(jī),2002(5).
[5] Wei Ruan Gong Si.XML3.0技術(shù)內(nèi)幕[M].北京:清華大學(xué)出版社,2001.
[6] EITEL H M.XML編程技術(shù)大全[M].北京:清華大學(xué)出版社,2002.
[7] 孫衛(wèi)琴.精通Struts:基于MVC的JAVA Web設(shè)計(jì)開(kāi)發(fā)[M].北京:電子工業(yè)出版社,2004.