李 宇,劉 彬
(攀枝花學(xué)院,四川 攀枝花 617000)
在互聯(lián)網(wǎng)技術(shù)的發(fā)展過程中,前端開發(fā)在較長的一段時間不被重視,大多數(shù)前端人員也只是開發(fā)HTML和Css,前端沒有自己的架構(gòu),甚至部分前端工作都由后臺完成。但隨著目前互聯(lián)網(wǎng)的高速發(fā)展,對系統(tǒng)的要求變得十分高,軟件系統(tǒng)的復(fù)雜性和軟件體系規(guī)模也在不斷地增長。在2017年雙十一當(dāng)天,淘寶系統(tǒng)頁面瀏覽量(Page View,PV)達400億次,涉及的軟件系統(tǒng)大大小小達數(shù)百個模塊。若還使用傳統(tǒng)的前后端耦合的方式,那么注定會有大量重復(fù)的代碼,當(dāng)需要對一個功能修改時則需要將前后臺都進行修改,代碼管理難度上升,系統(tǒng)維護麻煩。根據(jù)這種情況,本文介紹目前解決此類問題的前后端分離的開發(fā)模式,并以一個項目演示前后端分離的基本結(jié)構(gòu)。
在互聯(lián)網(wǎng)發(fā)展過程中,有很長的一段時間軟件開發(fā)模式都是使用的傳統(tǒng)開發(fā)的模式。其特點是通過后臺語言提供的模板來生成HTML頁面,然后通過服務(wù)器將生成的頁面返回給瀏覽器,由瀏覽器呈現(xiàn)給用戶。以Java語言為例,在傳統(tǒng)開發(fā)模式中,使用JSP作為模板引擎,JSP通過在HTML代碼中使用Java代碼或者特定的標(biāo)簽集合來封裝動態(tài)邏輯。當(dāng)客戶端請求JSP頁面時,服務(wù)器會將JSP編譯成為servlet后執(zhí)行。這樣做的好處是開發(fā)效率較高,但是在JSP嵌入Java代碼使得前后端邏輯耦合嚴重,前端人員在維護頁面必須要會JSP,使得學(xué)習(xí)成本增高,并且項目上線后維護也十分不便。
Ajax(異步的JavaScript和XML)是一種不需要刷新整個頁面僅對頁面中局部進行刷新的技術(shù)。使用Ajax后對頁面數(shù)據(jù)的更新不需要再刷新整個頁面,只需要后臺提供返回數(shù)據(jù)的API。在前端通過Ajax調(diào)用Api便可以對系統(tǒng)數(shù)據(jù)進行增刪改查等操作。通過這種方式將對請求的調(diào)用工作放在了前端進行,后臺開發(fā)人員不需要關(guān)注頁面,只提供符合要求的API,前端人員只需要根據(jù)后臺開發(fā)的API獲取數(shù)據(jù)即可,這樣將前后臺進行了一定程度的解耦。
隨著互聯(lián)網(wǎng)技術(shù)的高速發(fā)展,目前Web項目所需要應(yīng)付的場景和以往有著很大的不同,以往的時候我們將代碼、數(shù)據(jù)庫放在同一個服務(wù)器中,所有的壓力都由一個服務(wù)器承擔(dān)。但目前各個網(wǎng)站訪問量都有了很大的上升。如果還是將所有的應(yīng)用放在一個服務(wù)器中,很容易使得服務(wù)器崩潰,為解決這類問題,現(xiàn)在許多系統(tǒng)都是用集群或者分布式模式,將一個項目部署到多個服務(wù)器或者分為多個子項目分別部署。當(dāng)用戶發(fā)送請求時,走完一個請求的全部流程可能需要經(jīng)過多個服務(wù)器,還存在著請求跨域的問題,如果項目前后端耦合度較高,那么必然使得系統(tǒng)復(fù)雜性上升。為解決這一情況,前后端分離已經(jīng)變成了一種必然的趨勢。
前后端分離是指將前端和后端從之前的相互融合中分離開來,兩者不再共用一個Server,前端作為一個獨立Server存在。這種情況下使得一部分業(yè)務(wù)邏輯轉(zhuǎn)移到前端,后臺通過API將數(shù)據(jù)交給前端后對前端就已經(jīng)是無感知狀態(tài),后端不再接觸任何的HTML或者模板頁面,前端獲得數(shù)據(jù)后進行業(yè)務(wù)邏輯的處理。
目前市面上流行的前端框架分別為:VueJS,React,Angular,使用這些框架都能很好地實現(xiàn)前后端分離,其中VueJS和Angular都使用了MVVM的開發(fā)模式實現(xiàn)業(yè)務(wù)邏輯,MVVM是對MVC的一個改進,將其中的View的狀態(tài)和行為進行抽象化,將頁面和業(yè)務(wù)分開。視圖獨立于模型而存在,單獨對視圖或模型修改不會影響對方,同時可以將一些視圖邏輯放到一個ViewModel中,實現(xiàn)邏輯的重用。
下面以攀枝花學(xué)院學(xué)術(shù)成果展示系統(tǒng)的設(shè)計為例,分析前后端分離模式在軟件設(shè)計中的應(yīng)用。
3.1.1 Node.js
Node.js是一個JavaScript運行時環(huán)境,Node.js是一個事件驅(qū)動I/O服務(wù)端JavaScript環(huán)境,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度很快。但在本系統(tǒng)中并不直接使用Node.js進行系統(tǒng)開發(fā),而是使用其提供了NPM工具對前端系統(tǒng)進行打包構(gòu)建。
3.1.2 Vue.js
Vue.js是一套構(gòu)建用戶界面的漸進式框架。其核心只關(guān)注視圖層,并且非常容易學(xué)習(xí),非常容易與其他庫或已有項目整合。Vue完全有能力驅(qū)動采用單文件組件和Vue生態(tài)系統(tǒng)支持的庫開發(fā)的復(fù)雜單頁應(yīng)用。Vue的目標(biāo)是通過簡單的 API實現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。Vue自身不是一個全能框架,它只聚焦于視圖層。在前后端分離的開發(fā)模式下,Vue作為前端框架管理前端的路由以及數(shù)據(jù)信息。這樣就好似前端作為一個系統(tǒng)而存在,即使后期后端需要大范圍的重構(gòu),只要保證數(shù)據(jù)格式不變,前端將不會有任何影響。
3.2.1 后臺實現(xiàn)
該系統(tǒng)使用Spring+Springmvc+Mybatis框架搭建而成,后臺系統(tǒng)只對外提供數(shù)據(jù)接口,由前端通過API請求結(jié)構(gòu),后臺以Json格式的數(shù)據(jù)返回。在本系統(tǒng)中采用3層開發(fā)模式(Controller-Service-Dao),Controller是前端控制器,接收Client發(fā)送的請求并解析URL后將請求轉(zhuǎn)發(fā)給對應(yīng)的邏輯。進入到Service后對請求進行邏輯處理,根據(jù)不同的需求各自處理。如搜索服務(wù)請求solr服務(wù)器,爬蟲則調(diào)用python,其他請求同數(shù)據(jù)庫進行交互。從數(shù)據(jù)源取到數(shù)據(jù)后由Springmvc將數(shù)據(jù)轉(zhuǎn)換為Json格式返回給前端。
3.2.2 前端設(shè)計
該項目采用前后端分離的開發(fā)模式,前端獨立作為一個項目存在,使用Node.js打包構(gòu)建。系統(tǒng)的部分邏輯轉(zhuǎn)移到前端實現(xiàn),后臺給前端提供數(shù)據(jù)。本系統(tǒng)采用基于MVVM模式的VueJS框架,通過其模塊化,雙向數(shù)據(jù)綁定和自定義路由等功能來簡化系統(tǒng)的開發(fā)。
用戶發(fā)送請求后并不是直接對后臺進行請求,而是先轉(zhuǎn)到Vue的路由(Router),由路由決定加載哪一個視圖(View),渲染View的數(shù)據(jù)全部都在ViewModel中保存,當(dāng)需要從后臺獲取數(shù)據(jù)時Model和后臺進行數(shù)據(jù)交互,同時Model也會做一些前端邏輯處理。因為在MVVM模式中View和ViewModel是雙向綁定的,所以對ViewModel中數(shù)據(jù)的更新會直接更新View。
(1)創(chuàng)建項目結(jié)構(gòu)。
在項目路徑下創(chuàng)建public文件夾,在public文件夾下創(chuàng)建package.json文件。在該文件中列出需要的庫信息,在終端鍵入:npm install,npm會自動下載我們需要的庫文件,下載好后會在當(dāng)前文件夾下生成一個node_modules文件夾,庫文件放在該文件夾中。在public文件夾下創(chuàng)建src文件夾,用于存放項目的代碼文件。
(2)請求數(shù)據(jù)。
在src目錄下創(chuàng)建router.js文件,在該文件中編寫前端路由規(guī)則,導(dǎo)入Vue的路由組件,前端路由都從router.js開始,vue-router解析url后根據(jù)router.js文件的路由規(guī)則加載組件,在該組件中從后臺請求數(shù)據(jù),同時可以做一些其他的業(yè)務(wù)邏輯操作。
在加載到數(shù)據(jù)后,因為Vue中View和ViewModel是雙向綁定,所以只需要更新ViewModel即可更新View,Vue提供了進行綁定的關(guān)鍵字,只需在HTML中的標(biāo)簽上使用綁定的關(guān)鍵字即可實現(xiàn)雙向綁定。從后臺獲取到數(shù)據(jù)后通過vue的事件驅(qū)動即可實現(xiàn)數(shù)據(jù)的加載和其他操作,而不需要由程序員主動操作DOM,使得前端項目結(jié)構(gòu)十分清晰。本項目中使用Node.js的npm工具打包,在開發(fā)好后,通過在終端使用npm install命令即可對前端打包完成,將前后端代碼分別部署相互不產(chǎn)生干擾。
本文介紹了軟件開發(fā)中前后端模式的基本歷程,并以一種基于前后端分離的成果展示系統(tǒng)為例介紹了前后端分離的基本結(jié)構(gòu)。軟件開發(fā)中前后端進行分離后由后端提供數(shù)據(jù)然后前端來進行渲染使得項目分工明確,開發(fā)過程中前后端可以各自測試已經(jīng)完成的功能,最后將前后端進行對接,有效地提升開發(fā)效率。但同時需要注意的是由于前后端分離技術(shù)目前還不是十分成熟,并且由于在前端進行頁面渲染也不利于搜索引擎優(yōu)化(Search Engine Optimization,SEO),所以我們在選擇開發(fā)模式時應(yīng)根據(jù)項目需求決定,同時也應(yīng)多嘗試前后端分離的模式,促進前后端分離模式趨于成熟。