張文勝,陳 宏
(西安歐亞學院 陜西 西安 710065)
目前,隨著HTML 5與CSS 3的不斷發(fā)展,移動設備用Web網站或Web應用程序開發(fā)的需求在不斷擴大,“基于HTML 5、CSS 3和JavaScript開發(fā)的Web網站或Web應用程序才是未來的趨勢”這種觀點越來越被IT屆人士廣泛接受,越來越多的IT屆人士開始積極尋求一個能夠利用HTML 5與CSS 3進行Web網站與Web應用程序開發(fā)的框架[1]。
MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式,把軟件系統(tǒng)分為3個基本部分:模型(Model)、視圖(View)和控制器(Controller)。 MVC 模式的目的是實現(xiàn)一種動態(tài)的程序設計,使后續(xù)對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能。除此之外,此模式通過對復雜度的簡化,使程序結構更加直觀。軟件系統(tǒng)通過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。專業(yè)人員可以通過自身的專長分組:(控制器Controller)—負責轉發(fā)請求,對請求進行處理。(視圖View)—界面設計人員進行圖形界面設計。(模型Model)—程序員編寫程序應有的功能(實現(xiàn)算法等)、數(shù)據(jù)庫專家進行數(shù)據(jù)管理和數(shù)據(jù)庫設計(可以實現(xiàn)具體的功能)。
近五六年以來,各種尺寸的智能手機和平板電腦層出不窮,越來越多的人使用移動設備來訪問互聯(lián)網,這就給前端代碼的跨平臺性、復用性、易維護性帶來了更高的要求。如果有跨平臺的復用性好且易維護的框架的話,可以大大提高開發(fā)效率。因此前端開發(fā)人員也在不停地探索,MVC模型在Web后臺開發(fā)中應用廣泛,實現(xiàn)了展示模塊和數(shù)據(jù)邏輯處理模塊的分離。因此很多公司開始借鑒MVC在后端的運用,建立前端MVC架構,代表的框架有ExtJS、BackBone等[2]。
然而,手機移動前端開發(fā)越注重用戶體驗,也越給開發(fā)引入了可觀的復雜度,讓移動前端的開發(fā)變得更加困難,增加了發(fā)生過失(bugs)的可能性,也加大了軟件測試的復雜度,這些復雜化都將延長軟件開發(fā)過程,開發(fā)者不得不付出額外的開發(fā)代價去組織和管理自己的架構。
基于MVCS模式的手機移動前端的設計方法提出了解決上述問題的方法,使得前端重構成為可能,采用MVCS的軟件設計模式,可以保證代碼干凈、便于測試、容易維護。
除此之外,此模式還支持組件化編程,組件化的基礎是面向對象,在面向對象編程的基礎上將一個或多個小部件封裝到一起,成為一個模塊,讓其成為一個新的組件(適合我們需求的組件),每一個模塊都應當具備單獨運行的能力。組件化編程是面向對象的技術的一種近一步的發(fā)展延伸,類的概念仍然是組件技術中一個基礎的概念,但是組件技術更核心的概念是接口。
本文以圖書信息系統(tǒng)為例,給出了基于MVC模式的組件化的手機前端的原理及其實現(xiàn)步驟,并使之標準化,讓開發(fā)者更加專注于核心JS代碼的開發(fā),減少花費在編寫界面、組織代碼等重復性的工作上的時間。同時,將MVCS模型與MVC模型進行對比,驗證MVCS的有效性。
手機Web前端應用是移動互聯(lián)網應用的最佳形式,但是隨著系統(tǒng)版本的不斷升級,設備的差異不斷增大,移動客戶端應用開發(fā)同樣面臨著與Web前端開發(fā)一樣的兼容性開發(fā)效率和維護成本問題。組件化的Web前端設計架構基于Sencha Touch (ExtJS 整合 JQTouch、Rapha?l庫) 框架, 采用Model-View-Controller-Store(縮寫為 MVCS)模式,腳本文件按目錄命名約定分類存放,通過“組件化”的方式來配置和管理所需要的軟件功能,不僅使代碼的組織更加容易和清晰,而且減少代碼的編寫量,維護更為便捷[3]。
MVCS模式的目的是實現(xiàn)一種動態(tài)的程序設計,使后續(xù)對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能。除此之外,此模式通過對復雜度的簡化,使程序結構更加直觀。軟件系統(tǒng)通過對自身基本部分分離的同時也賦予了各個基本部分應有的功能。
MVCS模式與傳統(tǒng)Web應用的MVC有所不同,傳統(tǒng)Web應用中,用戶瀏覽器客戶端做低層次的交互,域邏輯主要集中在服務器端,因此,傳統(tǒng)Web應用的控制層、視圖層和模型層都分布在服務器端。也稱為服務器端MVC模式。
而作為手機前端的MVCS模式借鑒了經典的服務器端MVC模式,但存在一些變化,定義如下:
1)模型(Model)是一個域和其數(shù)據(jù)類型的集合。模型知道如何通過數(shù)據(jù)包的方式保留它們,并且能夠通過關聯(lián)被其它模型鏈接。一般與Stores一同使用來給grids或其它組件提供數(shù)據(jù)。
2)視圖(View)文件夾中定義了所有的 widget,每一個widget對應一個類文件。View的代碼屬于靜態(tài)代碼,可以使用工具自動生成。
3)控制器(Controller)文件夾中的控制器按管理范圍的不同劃分為不同的類文件,其中每一個控制邏輯都包括初始化、組件事件監(jiān)聽以及引用等。
4)數(shù)據(jù)存儲(Store)就是對通過網絡加載數(shù)據(jù)的過程的一個抽象,Store依賴于Model,通過關聯(lián)的Model對象來獲知如何將取回的數(shù)據(jù)對象化,以方便View展現(xiàn),所以View是依賴Store對象的;Store類似于服務器的(DAO)用在服務器端使用的 DAO(Data Access Object)模式[4]。
應用程序用來定義依賴項的地方主要有兩個,application本身和應用程序內部類。當創(chuàng)建一個MVC應用程序時,Ext.application會提供一個直觀的方式來設置應用程序會用到的數(shù)據(jù)模型、視圖、控制器、數(shù)據(jù)存儲器和配置文件等,如圖1所示。這5個配置項是用來加載應用程序常用文件(數(shù)據(jù)模型、視圖、控制器、存儲器、配置文件)的快捷方式[5]。
圖1 管理MVCS依賴項Fig.1 Managing dependencies with MVCS
由此可見,運用MVCS模型后,HTML里不再直接寫 JS代碼,JS按邏輯、職責分門別類存于不同的目錄,對應到不同的文件中。各個模塊之間需要盡量解耦,使得相互之間盡可能減少依賴,把界面(View)和數(shù)據(jù)存儲模型(Store)進行綁定,使得一方變化的時候另一方也會自動變化。
首先,設計一個WidgetA,這是一個tab panel用于在Viewport A中顯示圖書基本信息記錄,ModelA定義記錄的數(shù)據(jù)類型。StoreA負責檢索從服務器獲取的基本圖書數(shù)據(jù)。
那么,當用戶從WidgetA點擊一條記錄,一個窗口將打開,顯示的信息的數(shù)據(jù)類型來自ModelA。當然,這Store將負責從服務器檢索相應數(shù)據(jù)。打開WidgetB,home窗口開啟。
同時,ControllerA捕獲來自WidgetA的Click事件和加載WidgetA所需數(shù)據(jù)信息,最終顯示對應的圖書列表。描述模型如圖2所示。
圖2 元數(shù)據(jù)描述模型Fig.2 Metadata description model
在應用架構創(chuàng)建的應用時,定義統(tǒng)一的約定,尤其是統(tǒng)一的目錄結構。這個結構要求所有類文件都放到app目錄下,在該目錄下,可根據(jù)命名空間劃建立 models、views、controllers和stores等4個子目錄。嚴格遵守控制器、數(shù)據(jù)模型、數(shù)據(jù)存儲、視圖這4個文件夾的命名約定,把對視覺界面、交互邏輯和數(shù)據(jù)的處理清晰地分開,這可以確??梢允褂肧DK Tools beta對應用進行優(yōu)化[6]。目錄結構如圖3所示。
圖3 應用程序目錄結構Fig.3 The directory structure of the application
View模塊需要構建一個tab Panel組件,將整個界面布局設置為使用Panel面板,并且設置了fullscreen屬性為true,應用啟動后,首先顯示的是Ext.Container,TabPanel的TabBar泊位在應用視圖窗口的底部,在點擊時,就會切換到對應的容器界面。
Model模塊分為BookData和Sectionlist,分別定義書籍信息的基本數(shù)據(jù)類型和圖書列表數(shù)據(jù)類型。每個模型定義分別包含id、img、name和 items及 products等字段,針對定義字段編寫校驗規(guī)則,如name字段的length,products字段的 format等。
Store模塊同樣也分為BookDataStore,為數(shù)據(jù)列表組件提供顯示數(shù)據(jù)。獲得數(shù)據(jù)后還需要通過數(shù)據(jù)解析器將這些數(shù)據(jù)進行解析,從而成為客戶端認可的符合一定格式的數(shù)據(jù)。
Proxy(代理)是應用架構從Store,Model加載和保存數(shù)據(jù)的方法??晒┻x擇的有AJAX、JSON-P和HTML5 localStorage以及其它的代理。這里使用AJAX代理,告訴程序從‘data/book.json’這個url去加載數(shù)據(jù)。
Controller的目的是監(jiān)聽事件并作出合適的響應動作通常這些事件來是View上面的用戶操作。Controller模塊Book Controller捕獲來自table Panel的Click事件和加載Boo kListing所需數(shù)據(jù)信息,最終顯示對應的圖書列表和圖片。
Data模塊放置資源文件,是應用程序通過 AJAX方式與服務器端交換的數(shù)據(jù),返回的數(shù)據(jù)格式是輕量級的文本數(shù)據(jù)交換格式json。
每個ExtJS的應用都必須從創(chuàng)建一個Ext.app.Application實例開始,app.js創(chuàng)建一個Application實例并完成初始化。
MVCS模型增加Store(數(shù)據(jù)存儲)的目的就可以使Proxy(數(shù)據(jù)代理)在Model(模型)與數(shù)據(jù)之間搭建橋梁,數(shù)據(jù)代理將在它們之間建立關系,然后通過數(shù)據(jù)代理進行相關的GRUD(Create, Read, Update, Delete)操作。
Store數(shù)據(jù)集是一個客戶端數(shù)據(jù)模型對象Model的緩存,它可以為模型組件提供數(shù)據(jù)輸入 (例如:GridPanel、ComboBox、DataView等),Store通過數(shù)據(jù)代理加載數(shù)據(jù),也可以手工調用loadData等方法加載數(shù)據(jù),解析后的數(shù)據(jù)對象緩存在Store數(shù)據(jù)集中,并通過存取函數(shù)進行訪問。
此外,此模式還支持訪問歷史(應用將獲得完整的后退按鈕功能,其中的任意部分都可以被鏈接到)、深度鏈接(深度鏈接可以打開應用程序中的任意屏幕)、設備配置文件(共享通用代碼的同時,輕松為手機、平板電腦還有其他設備定制應用程序用戶界面)等。
本文以圖書信息管理系統(tǒng)為例進行分析說明。使用MVCS模型實現(xiàn)了圖書信息手機Web前端展示,如圖4~圖7所示。
TabBar上的兩個導航按鈕,分別進行主頁面和查詢頁面的切換,如圖4和圖5所示。
圖4 應用程序主頁Fig.4 The home page of the application
圖5 出版社目錄結構Fig.5 The directory structure of publishing house
在應用中,使用動態(tài)生成的列表羅列圖書的基本信息,可出版社和地區(qū)的不同進行自動羅列,處理事件被正確地綁定到每行出版社和地區(qū)的單擊事件上,然后通過相應單擊事件,顯示相關書籍的名稱和封面圖片。如圖6和圖7所示。
MVCS模式以標準的方式展示數(shù)據(jù),降低了開發(fā)難度,使整個手機前端代碼的規(guī)劃更規(guī)范,前端實時數(shù)據(jù)的圖表和圖形的展示更容易擴展和維護,更適合多人協(xié)作編寫復雜界面。
圖6 出版社圖書列表Fig.6 Book list of the publishing house
圖7 地區(qū)圖書列表Fig.7 The area agency list of books
本系統(tǒng)使用跨平臺的開發(fā)框架PhoneGap/Cordova來部署手機應用,這是一個專業(yè)的移動應用開發(fā)框架,也是一個全面的Web App開發(fā)的框架,提供了以Web形式來訪問終端設備的API的功能。這對于采用Web App進行開發(fā)就可以避免了原生開發(fā)的某些功能。Cordova只是個原生外殼,App的內核是一個完整的Web App,需要調用的原生功能將以原生插件的形式實現(xiàn),以暴露JS接口的方式調用。
本文在MVC的基礎上,通過組件化擴展形成MVCS,并通過實際應用給出了實現(xiàn)方法。
MVCS與MVC模型相比,把以前的業(yè)務模型拆分成數(shù)據(jù)模型Model和數(shù)據(jù)存儲模型Store,從數(shù)據(jù)庫的角度講,Store類封裝了一個客戶端的記錄對象的緩存,為UI組件提供了數(shù)據(jù)的入口。這是 Proxy、Reader/Writer更細顆粒的職責分工下以及引入Model后必然帶來的結果。這樣的優(yōu)點就是Store作為數(shù)據(jù)訪問層就可避免在UI組件里找數(shù)據(jù)了,通過Ajax技術,把瀏覽器當作表現(xiàn)層,服務器端當作數(shù)據(jù)訪問層。那么,服務器只通過XML格式或JSON格式提供必要數(shù)據(jù)就行了,全部的表現(xiàn)可在客戶端通過MVCS架構實現(xiàn),這樣就避免了服務器端代碼和客戶端代碼混搭在一起的問題,從而實現(xiàn)了客戶端與服務器端的脫鉤。
為了便于在不同的移動設備上部署,profile是配置各個平臺的一個啟動配置文件,如果應用程序需要在不同的平臺及不同的設備上運行,則可能需要在此配置每個設備平臺的專屬配置文件,例如在Android、iPhone或者iPad等平臺及設備上。
隨著手機Web前端的發(fā)展,工程化的特點日趨明顯,MVCS在手機Web前端技術的規(guī)范化和可維護、可擴展上做了一些探索,在未來的工作中,會進一步對MVCS模式進行優(yōu)化和完善,提高模塊的可復用性、整個系統(tǒng)的容錯性和靈活性。
[1]陸凌牛.Sencha Touch權威指南[M].北京:機械工業(yè)出版社,2012.
[2]于春娜,王晨升,楊光,等.Web前端MVC框架的意義研究[J].產業(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è)級組態(tài)式Web前端設計方法研究與應用[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.