張文勝,陳 宏
(西安歐亞學(xué)院 陜西 西安 710065)
目前,隨著HTML 5與CSS 3的不斷發(fā)展,移動(dòng)設(shè)備用Web網(wǎng)站或Web應(yīng)用程序開(kāi)發(fā)的需求在不斷擴(kuò)大,“基于HTML 5、CSS 3和JavaScript開(kāi)發(fā)的Web網(wǎng)站或Web應(yīng)用程序才是未來(lái)的趨勢(shì)”這種觀點(diǎn)越來(lái)越被IT屆人士廣泛接受,越來(lái)越多的IT屆人士開(kāi)始積極尋求一個(gè)能夠利用HTML 5與CSS 3進(jìn)行Web網(wǎng)站與Web應(yīng)用程序開(kāi)發(fā)的框架[1]。
MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構(gòu)模式,把軟件系統(tǒng)分為3個(gè)基本部分:模型(Model)、視圖(View)和控制器(Controller)。 MVC 模式的目的是實(shí)現(xiàn)一種動(dòng)態(tài)的程序設(shè)計(jì),使后續(xù)對(duì)程序的修改和擴(kuò)展簡(jiǎn)化,并且使程序某一部分的重復(fù)利用成為可能。除此之外,此模式通過(guò)對(duì)復(fù)雜度的簡(jiǎn)化,使程序結(jié)構(gòu)更加直觀。軟件系統(tǒng)通過(guò)對(duì)自身基本部分分離的同時(shí)也賦予了各個(gè)基本部分應(yīng)有的功能。專(zhuān)業(yè)人員可以通過(guò)自身的專(zhuān)長(zhǎng)分組:(控制器Controller)—負(fù)責(zé)轉(zhuǎn)發(fā)請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理。(視圖View)—界面設(shè)計(jì)人員進(jìn)行圖形界面設(shè)計(jì)。(模型Model)—程序員編寫(xiě)程序應(yīng)有的功能(實(shí)現(xiàn)算法等)、數(shù)據(jù)庫(kù)專(zhuān)家進(jìn)行數(shù)據(jù)管理和數(shù)據(jù)庫(kù)設(shè)計(jì)(可以實(shí)現(xiàn)具體的功能)。
近五六年以來(lái),各種尺寸的智能手機(jī)和平板電腦層出不窮,越來(lái)越多的人使用移動(dòng)設(shè)備來(lái)訪問(wèn)互聯(lián)網(wǎng),這就給前端代碼的跨平臺(tái)性、復(fù)用性、易維護(hù)性帶來(lái)了更高的要求。如果有跨平臺(tái)的復(fù)用性好且易維護(hù)的框架的話,可以大大提高開(kāi)發(fā)效率。因此前端開(kāi)發(fā)人員也在不停地探索,MVC模型在Web后臺(tái)開(kāi)發(fā)中應(yīng)用廣泛,實(shí)現(xiàn)了展示模塊和數(shù)據(jù)邏輯處理模塊的分離。因此很多公司開(kāi)始借鑒MVC在后端的運(yùn)用,建立前端MVC架構(gòu),代表的框架有ExtJS、BackBone等[2]。
然而,手機(jī)移動(dòng)前端開(kāi)發(fā)越注重用戶體驗(yàn),也越給開(kāi)發(fā)引入了可觀的復(fù)雜度,讓移動(dòng)前端的開(kāi)發(fā)變得更加困難,增加了發(fā)生過(guò)失(bugs)的可能性,也加大了軟件測(cè)試的復(fù)雜度,這些復(fù)雜化都將延長(zhǎng)軟件開(kāi)發(fā)過(guò)程,開(kāi)發(fā)者不得不付出額外的開(kāi)發(fā)代價(jià)去組織和管理自己的架構(gòu)。
基于MVCS模式的手機(jī)移動(dòng)前端的設(shè)計(jì)方法提出了解決上述問(wèn)題的方法,使得前端重構(gòu)成為可能,采用MVCS的軟件設(shè)計(jì)模式,可以保證代碼干凈、便于測(cè)試、容易維護(hù)。
除此之外,此模式還支持組件化編程,組件化的基礎(chǔ)是面向?qū)ο?,在面向?qū)ο缶幊痰幕A(chǔ)上將一個(gè)或多個(gè)小部件封裝到一起,成為一個(gè)模塊,讓其成為一個(gè)新的組件(適合我們需求的組件),每一個(gè)模塊都應(yīng)當(dāng)具備單獨(dú)運(yùn)行的能力。組件化編程是面向?qū)ο蟮募夹g(shù)的一種近一步的發(fā)展延伸,類(lèi)的概念仍然是組件技術(shù)中一個(gè)基礎(chǔ)的概念,但是組件技術(shù)更核心的概念是接口。
本文以圖書(shū)信息系統(tǒng)為例,給出了基于MVC模式的組件化的手機(jī)前端的原理及其實(shí)現(xiàn)步驟,并使之標(biāo)準(zhǔn)化,讓開(kāi)發(fā)者更加專(zhuān)注于核心JS代碼的開(kāi)發(fā),減少花費(fèi)在編寫(xiě)界面、組織代碼等重復(fù)性的工作上的時(shí)間。同時(shí),將MVCS模型與MVC模型進(jìn)行對(duì)比,驗(yàn)證MVCS的有效性。
手機(jī)Web前端應(yīng)用是移動(dòng)互聯(lián)網(wǎng)應(yīng)用的最佳形式,但是隨著系統(tǒng)版本的不斷升級(jí),設(shè)備的差異不斷增大,移動(dòng)客戶端應(yīng)用開(kāi)發(fā)同樣面臨著與Web前端開(kāi)發(fā)一樣的兼容性開(kāi)發(fā)效率和維護(hù)成本問(wèn)題。組件化的Web前端設(shè)計(jì)架構(gòu)基于Sencha Touch (ExtJS 整合 JQTouch、Rapha?l庫(kù)) 框架, 采用Model-View-Controller-Store(縮寫(xiě)為 MVCS)模式,腳本文件按目錄命名約定分類(lèi)存放,通過(guò)“組件化”的方式來(lái)配置和管理所需要的軟件功能,不僅使代碼的組織更加容易和清晰,而且減少代碼的編寫(xiě)量,維護(hù)更為便捷[3]。
MVCS模式的目的是實(shí)現(xiàn)一種動(dòng)態(tài)的程序設(shè)計(jì),使后續(xù)對(duì)程序的修改和擴(kuò)展簡(jiǎn)化,并且使程序某一部分的重復(fù)利用成為可能。除此之外,此模式通過(guò)對(duì)復(fù)雜度的簡(jiǎn)化,使程序結(jié)構(gòu)更加直觀。軟件系統(tǒng)通過(guò)對(duì)自身基本部分分離的同時(shí)也賦予了各個(gè)基本部分應(yīng)有的功能。
MVCS模式與傳統(tǒng)Web應(yīng)用的MVC有所不同,傳統(tǒng)Web應(yīng)用中,用戶瀏覽器客戶端做低層次的交互,域邏輯主要集中在服務(wù)器端,因此,傳統(tǒng)Web應(yīng)用的控制層、視圖層和模型層都分布在服務(wù)器端。也稱(chēng)為服務(wù)器端MVC模式。
而作為手機(jī)前端的MVCS模式借鑒了經(jīng)典的服務(wù)器端MVC模式,但存在一些變化,定義如下:
1)模型(Model)是一個(gè)域和其數(shù)據(jù)類(lèi)型的集合。模型知道如何通過(guò)數(shù)據(jù)包的方式保留它們,并且能夠通過(guò)關(guān)聯(lián)被其它模型鏈接。一般與Stores一同使用來(lái)給grids或其它組件提供數(shù)據(jù)。
2)視圖(View)文件夾中定義了所有的 widget,每一個(gè)widget對(duì)應(yīng)一個(gè)類(lèi)文件。View的代碼屬于靜態(tài)代碼,可以使用工具自動(dòng)生成。
3)控制器(Controller)文件夾中的控制器按管理范圍的不同劃分為不同的類(lèi)文件,其中每一個(gè)控制邏輯都包括初始化、組件事件監(jiān)聽(tīng)以及引用等。
4)數(shù)據(jù)存儲(chǔ)(Store)就是對(duì)通過(guò)網(wǎng)絡(luò)加載數(shù)據(jù)的過(guò)程的一個(gè)抽象,Store依賴于Model,通過(guò)關(guān)聯(lián)的Model對(duì)象來(lái)獲知如何將取回的數(shù)據(jù)對(duì)象化,以方便View展現(xiàn),所以View是依賴Store對(duì)象的;Store類(lèi)似于服務(wù)器的(DAO)用在服務(wù)器端使用的 DAO(Data Access Object)模式[4]。
應(yīng)用程序用來(lái)定義依賴項(xiàng)的地方主要有兩個(gè),application本身和應(yīng)用程序內(nèi)部類(lèi)。當(dāng)創(chuàng)建一個(gè)MVC應(yīng)用程序時(shí),Ext.application會(huì)提供一個(gè)直觀的方式來(lái)設(shè)置應(yīng)用程序會(huì)用到的數(shù)據(jù)模型、視圖、控制器、數(shù)據(jù)存儲(chǔ)器和配置文件等,如圖1所示。這5個(gè)配置項(xiàng)是用來(lái)加載應(yīng)用程序常用文件(數(shù)據(jù)模型、視圖、控制器、存儲(chǔ)器、配置文件)的快捷方式[5]。

圖1 管理MVCS依賴項(xiàng)Fig.1 Managing dependencies with MVCS
由此可見(jiàn),運(yùn)用MVCS模型后,HTML里不再直接寫(xiě) JS代碼,JS按邏輯、職責(zé)分門(mén)別類(lèi)存于不同的目錄,對(duì)應(yīng)到不同的文件中。各個(gè)模塊之間需要盡量解耦,使得相互之間盡可能減少依賴,把界面(View)和數(shù)據(jù)存儲(chǔ)模型(Store)進(jìn)行綁定,使得一方變化的時(shí)候另一方也會(huì)自動(dòng)變化。
首先,設(shè)計(jì)一個(gè)WidgetA,這是一個(gè)tab panel用于在Viewport A中顯示圖書(shū)基本信息記錄,ModelA定義記錄的數(shù)據(jù)類(lèi)型。StoreA負(fù)責(zé)檢索從服務(wù)器獲取的基本圖書(shū)數(shù)據(jù)。
那么,當(dāng)用戶從WidgetA點(diǎn)擊一條記錄,一個(gè)窗口將打開(kāi),顯示的信息的數(shù)據(jù)類(lèi)型來(lái)自ModelA。當(dāng)然,這Store將負(fù)責(zé)從服務(wù)器檢索相應(yīng)數(shù)據(jù)。打開(kāi)WidgetB,home窗口開(kāi)啟。
同時(shí),ControllerA捕獲來(lái)自WidgetA的Click事件和加載WidgetA所需數(shù)據(jù)信息,最終顯示對(duì)應(yīng)的圖書(shū)列表。描述模型如圖2所示。

圖2 元數(shù)據(jù)描述模型Fig.2 Metadata description model
在應(yīng)用架構(gòu)創(chuàng)建的應(yīng)用時(shí),定義統(tǒng)一的約定,尤其是統(tǒng)一的目錄結(jié)構(gòu)。這個(gè)結(jié)構(gòu)要求所有類(lèi)文件都放到app目錄下,在該目錄下,可根據(jù)命名空間劃建立 models、views、controllers和stores等4個(gè)子目錄。嚴(yán)格遵守控制器、數(shù)據(jù)模型、數(shù)據(jù)存儲(chǔ)、視圖這4個(gè)文件夾的命名約定,把對(duì)視覺(jué)界面、交互邏輯和數(shù)據(jù)的處理清晰地分開(kāi),這可以確??梢允褂肧DK Tools beta對(duì)應(yīng)用進(jìn)行優(yōu)化[6]。目錄結(jié)構(gòu)如圖3所示。

圖3 應(yīng)用程序目錄結(jié)構(gòu)Fig.3 The directory structure of the application
View模塊需要構(gòu)建一個(gè)tab Panel組件,將整個(gè)界面布局設(shè)置為使用Panel面板,并且設(shè)置了fullscreen屬性為true,應(yīng)用啟動(dòng)后,首先顯示的是Ext.Container,TabPanel的TabBar泊位在應(yīng)用視圖窗口的底部,在點(diǎn)擊時(shí),就會(huì)切換到對(duì)應(yīng)的容器界面。
Model模塊分為BookData和Sectionlist,分別定義書(shū)籍信息的基本數(shù)據(jù)類(lèi)型和圖書(shū)列表數(shù)據(jù)類(lèi)型。每個(gè)模型定義分別包含id、img、name和 items及 products等字段,針對(duì)定義字段編寫(xiě)校驗(yàn)規(guī)則,如name字段的length,products字段的 format等。
Store模塊同樣也分為BookDataStore,為數(shù)據(jù)列表組件提供顯示數(shù)據(jù)。獲得數(shù)據(jù)后還需要通過(guò)數(shù)據(jù)解析器將這些數(shù)據(jù)進(jìn)行解析,從而成為客戶端認(rèn)可的符合一定格式的數(shù)據(jù)。
Proxy(代理)是應(yīng)用架構(gòu)從Store,Model加載和保存數(shù)據(jù)的方法??晒┻x擇的有AJAX、JSON-P和HTML5 localStorage以及其它的代理。這里使用AJAX代理,告訴程序從‘data/book.json’這個(gè)url去加載數(shù)據(jù)。
Controller的目的是監(jiān)聽(tīng)事件并作出合適的響應(yīng)動(dòng)作通常這些事件來(lái)是View上面的用戶操作。Controller模塊Book Controller捕獲來(lái)自table Panel的Click事件和加載Boo kListing所需數(shù)據(jù)信息,最終顯示對(duì)應(yīng)的圖書(shū)列表和圖片。
Data模塊放置資源文件,是應(yīng)用程序通過(guò) AJAX方式與服務(wù)器端交換的數(shù)據(jù),返回的數(shù)據(jù)格式是輕量級(jí)的文本數(shù)據(jù)交換格式j(luò)son。
每個(gè)ExtJS的應(yīng)用都必須從創(chuàng)建一個(gè)Ext.app.Application實(shí)例開(kāi)始,app.js創(chuàng)建一個(gè)Application實(shí)例并完成初始化。
MVCS模型增加Store(數(shù)據(jù)存儲(chǔ))的目的就可以使Proxy(數(shù)據(jù)代理)在Model(模型)與數(shù)據(jù)之間搭建橋梁,數(shù)據(jù)代理將在它們之間建立關(guān)系,然后通過(guò)數(shù)據(jù)代理進(jìn)行相關(guān)的GRUD(Create, Read, Update, Delete)操作。
Store數(shù)據(jù)集是一個(gè)客戶端數(shù)據(jù)模型對(duì)象Model的緩存,它可以為模型組件提供數(shù)據(jù)輸入 (例如:GridPanel、ComboBox、DataView等),Store通過(guò)數(shù)據(jù)代理加載數(shù)據(jù),也可以手工調(diào)用loadData等方法加載數(shù)據(jù),解析后的數(shù)據(jù)對(duì)象緩存在Store數(shù)據(jù)集中,并通過(guò)存取函數(shù)進(jìn)行訪問(wèn)。
此外,此模式還支持訪問(wèn)歷史(應(yīng)用將獲得完整的后退按鈕功能,其中的任意部分都可以被鏈接到)、深度鏈接(深度鏈接可以打開(kāi)應(yīng)用程序中的任意屏幕)、設(shè)備配置文件(共享通用代碼的同時(shí),輕松為手機(jī)、平板電腦還有其他設(shè)備定制應(yīng)用程序用戶界面)等。
本文以圖書(shū)信息管理系統(tǒng)為例進(jìn)行分析說(shuō)明。使用MVCS模型實(shí)現(xiàn)了圖書(shū)信息手機(jī)Web前端展示,如圖4~圖7所示。
TabBar上的兩個(gè)導(dǎo)航按鈕,分別進(jìn)行主頁(yè)面和查詢頁(yè)面的切換,如圖4和圖5所示。

圖4 應(yīng)用程序主頁(yè)Fig.4 The home page of the application

圖5 出版社目錄結(jié)構(gòu)Fig.5 The directory structure of publishing house
在應(yīng)用中,使用動(dòng)態(tài)生成的列表羅列圖書(shū)的基本信息,可出版社和地區(qū)的不同進(jìn)行自動(dòng)羅列,處理事件被正確地綁定到每行出版社和地區(qū)的單擊事件上,然后通過(guò)相應(yīng)單擊事件,顯示相關(guān)書(shū)籍的名稱(chēng)和封面圖片。如圖6和圖7所示。
MVCS模式以標(biāo)準(zhǔn)的方式展示數(shù)據(jù),降低了開(kāi)發(fā)難度,使整個(gè)手機(jī)前端代碼的規(guī)劃更規(guī)范,前端實(shí)時(shí)數(shù)據(jù)的圖表和圖形的展示更容易擴(kuò)展和維護(hù),更適合多人協(xié)作編寫(xiě)復(fù)雜界面。

圖6 出版社圖書(shū)列表Fig.6 Book list of the publishing house

圖7 地區(qū)圖書(shū)列表Fig.7 The area agency list of books
本系統(tǒng)使用跨平臺(tái)的開(kāi)發(fā)框架PhoneGap/Cordova來(lái)部署手機(jī)應(yīng)用,這是一個(gè)專(zhuān)業(yè)的移動(dòng)應(yīng)用開(kāi)發(fā)框架,也是一個(gè)全面的Web App開(kāi)發(fā)的框架,提供了以Web形式來(lái)訪問(wèn)終端設(shè)備的API的功能。這對(duì)于采用Web App進(jìn)行開(kāi)發(fā)就可以避免了原生開(kāi)發(fā)的某些功能。Cordova只是個(gè)原生外殼,App的內(nèi)核是一個(gè)完整的Web App,需要調(diào)用的原生功能將以原生插件的形式實(shí)現(xiàn),以暴露JS接口的方式調(diào)用。
本文在MVC的基礎(chǔ)上,通過(guò)組件化擴(kuò)展形成MVCS,并通過(guò)實(shí)際應(yīng)用給出了實(shí)現(xiàn)方法。
MVCS與MVC模型相比,把以前的業(yè)務(wù)模型拆分成數(shù)據(jù)模型Model和數(shù)據(jù)存儲(chǔ)模型Store,從數(shù)據(jù)庫(kù)的角度講,Store類(lèi)封裝了一個(gè)客戶端的記錄對(duì)象的緩存,為UI組件提供了數(shù)據(jù)的入口。這是 Proxy、Reader/Writer更細(xì)顆粒的職責(zé)分工下以及引入Model后必然帶來(lái)的結(jié)果。這樣的優(yōu)點(diǎn)就是Store作為數(shù)據(jù)訪問(wèn)層就可避免在UI組件里找數(shù)據(jù)了,通過(guò)Ajax技術(shù),把瀏覽器當(dāng)作表現(xiàn)層,服務(wù)器端當(dāng)作數(shù)據(jù)訪問(wèn)層。那么,服務(wù)器只通過(guò)XML格式或JSON格式提供必要數(shù)據(jù)就行了,全部的表現(xiàn)可在客戶端通過(guò)MVCS架構(gòu)實(shí)現(xiàn),這樣就避免了服務(wù)器端代碼和客戶端代碼混搭在一起的問(wèn)題,從而實(shí)現(xiàn)了客戶端與服務(wù)器端的脫鉤。
為了便于在不同的移動(dòng)設(shè)備上部署,profile是配置各個(gè)平臺(tái)的一個(gè)啟動(dòng)配置文件,如果應(yīng)用程序需要在不同的平臺(tái)及不同的設(shè)備上運(yùn)行,則可能需要在此配置每個(gè)設(shè)備平臺(tái)的專(zhuān)屬配置文件,例如在Android、iPhone或者iPad等平臺(tái)及設(shè)備上。
隨著手機(jī)Web前端的發(fā)展,工程化的特點(diǎn)日趨明顯,MVCS在手機(jī)Web前端技術(shù)的規(guī)范化和可維護(hù)、可擴(kuò)展上做了一些探索,在未來(lái)的工作中,會(huì)進(jìn)一步對(duì)MVCS模式進(jìn)行優(yōu)化和完善,提高模塊的可復(fù)用性、整個(gè)系統(tǒng)的容錯(cuò)性和靈活性。
[1]陸凌牛.Sencha Touch權(quán)威指南[M].北京:機(jī)械工業(yè)出版社,2012.
[2]于春娜,王晨升,楊光,等.Web前端MVC框架的意義研究[J].產(chǎn)業(yè)與科技論壇,2014,13(1):52-53.YU Chun-na,WANG Chen-sheng,YANG Guang,et al.Significance of Web in front of MVC framework[J].Estate and Science Tribune,2014,13(1):52-53.
[3]Sencha Inc.Sencha:The Authority in HTML5 Performance[EB/OL].[2014-01-01].?http://www.sencha.com/products/touch.
[4]張文勝,陳宏.企業(yè)級(jí)組態(tài)式Web前端設(shè)計(jì)方法研究與應(yīng)用[J].電子設(shè)計(jì)工程,2014,22(17):162-164.ZHANG Wen-sheng,CHEN Hong.The research and application of configuration software in the web front-end design method[J].Electronic Design Engineering,2014,22(17):162-164.
[5]Sencha Inc.Touch 2.0.2 Sencha Docs[EB/OL].[2014-01-01].http://docs.sencha.com/touch/2.0.2/#!/guide/mvc_depen dencies.
[6]Loiane Groner.Sencha Architect App Development[M].Packt Publishing Limited,2013.