前端MV*框架的意義

民工精髓發表於2013-10-22

經常有人質疑,在前端搞MV*有什麼意義?也有人提出這樣的疑問:以AngularJS,Knockout,BackBone為代表的MV*框架,它跟jQuery這樣的框架有什麼區別?我jQuery用得好好的,有什麼必要再引入這種框架?

回答這些問題之前,先要理清一些歷史,前端從什麼時候開始有框架的?

早期前端都是比較簡單,基本以頁面為工作單元,內容以瀏覽型為主,也偶爾有簡單的表單操作,這個時期每個介面上只有很少的JavaScript邏輯,基本不太需要框架。隨著AJAX的出現,Web2.0的興起,人們可以在頁面上可以做比較複雜的事情了,然後前端框架才真正出現了,以jQuery為代表,針對介面上常見的DOM操作,遠端請求,資料處理等作了封裝,也有專注於處理資料的Underscore,嚴格來說,這些都不能算框架,而是算庫。

庫和框架是有一些區別的:庫是一種工具,我提供了,你可以不用,即使你用了,也沒影響你自己的程式碼結構。框架則是面向一個領域,提供一套解決方案,如果你用我,就得按照我的方式辦事。按照這個定義,jQuery和Underscore都只能算是庫,ExtJS和dojo算框架。

MV*框架又是為什麼興起的呢?它的出現,伴隨著一些Web產品逐漸往應用方向發展,遇到了在C/S領域相同的問題:由於前端功能的增強、程式碼的膨脹,導致不得不做“前端的架構”這個事情了。

很多做後端開發的人對前端架構很不屑,認為前端只是很薄的一層東西,做架構幹什麼?什麼,不但要搞架構,還要搞MVC?Java Struts的MVC中,整個前端都只能算是View而已,你還要在這個View裡面劃分模型和控制器等其他東西?他們中的多數對這個很不屑,但Web前端隨著複雜度的增加,很多地方跟客戶端已經沒有本質區別了。

jQuery的思維方式是:以DOM操作為中心
MV*框架的思維方式是:以模型為中心,DOM操作只是附加

所以回到那個問題上,jQuery滿足了你的業務需要,你還有什麼必要引入MV*框架?

這個是要看產品型別的,如果是頁面型產品,多數確實不太需要它,因為頁面中的JavaScript程式碼,處理互動的絕對遠遠超過處理模型的,但是如果是應用軟體類產品,這就太需要了。

長期做某個行業軟體的公司,一般都會沉澱下來一些業務元件,主要體現在資料模型、業務規則和業務流程,這些元件基本都存在於後端,在前端很少有相應的組織。在以往的經驗裡,他們是有做MVC的,也嘗試做了一些介面元件,但做法比較過時,比如說使用JSF或者GWT這樣的方式。

JSF的問題是什麼?它的問題並不在於介面跟邏輯混合,所謂的縱向切分元件,Polymer這種純前端框架也是這麼切分的,它問題在於元件的生成和渲染不在同一個地方。所以,邏輯程式碼的位置很尷尬,如果這個介面簡單還好說,複雜起來就很麻煩了,就是很多明明是前端邏輯程式碼,卻需要通過後端去生成。

GWT這種方式相對要好一些,它的問題是留給UI調節的餘地太小了,比較缺乏靈活性。

這類基於某種服務端技術的元件化方式有一些侷限性,比如它較大程度限制了前端的發揮,在早一些的時候,這種方式可能還不錯,但是現在隨著時代發展,使用者對前端使用者體驗要求越來越高,需要我們把很大一部分精力繼續放回前端來。JSF等方案的另外一個問題是繫結了某種服務端環境,很難切換到另外一種後端上,如果碰上要用Hybird方式開發,想複用一些前端邏輯,幾乎毫無可能。

那麼,我們看看純前端的框架,看看都是怎麼解決這些問題的。以Google為例,它推出了兩個框架,Polymer和Angular,而且處於並行發展的階段,這兩者理念還有不小的差別,給不少人帶來了困惑。

Polymer切分元件的方式有點類似JSF,它跟HTML5標準中的Shadow DOM和Element有很大聯絡,這種切分元件的方式非常直觀,每個元件都是端到端的,包含UI和邏輯,直接放置到某個介面上就能用,這種方式很容易被業務開發人員接受,但裡面的時序比較難處理。

比如說,有兩個元件,裡面各包含一個下拉框,有資料的聯動關係,因為它們處在兩個不同的元件裡,聯動的處理程式碼就很難寫,考慮到元件的特點,要儘量隱藏自己的內部實現,所以從外部獲取元件內部的某個元素要繞一層,而元件不能依賴其他外部的東西,所以到最後只有通過事件去實現,這個聯動程式碼寫好了應當放在哪裡,也是個大問題。我們的例子僅僅是這麼簡單,就要繞這麼個大圈子才能保證時序,如果場景比較複雜,非常難以控制。

如果同樣的元件在某個介面被複用多次,資料的一致性也很難保證,設想一下某個介面存在兩個一樣的下拉框,分別處於不同元件中,兩者的資料都需要分別去載入,這個過程是有浪費的,更嚴重的是,如果這個下拉框對應的資料有更新,很難把每個例項都更新一遍,這個處理過程是非常麻煩的。

Angular框架處理問題的方式跟它有所不同,它是水平分層,所有這些資料訪問邏輯都跟UI徹底分離,所以可以很輕鬆地把這個邏輯程式碼寫出來,這麼一來,前面所述端到端的元件就徹底退化,變成只有介面展現了。

看看剛才碰到的兩個問題,第一個,模型程式碼按照業務領域進行劃分,獲取的資料放在兩個不同的陣列,然後通過雙向繫結跟UI產生關聯,如果UI上一個下拉框選中項發生變更,只需要監控這個取值項,然後更新另一個下拉框的取值列表即可,完全不需要繞彎子。即使這兩個處於不同模型中,也可以用類似後端的方式,採用事件匯流排等機制去完成通訊。

第二個更簡單了,複用的元件其實只有UI,也就是說,只有UI是多例項的,模型其實只有一份,比如說一個地區的樹形結構,即使一個介面上同時有維護和使用兩種功能,都可以共享同一份模型,當維護這邊對資料進行了更新,就實時反饋到模型中,然後由雙向繫結再把這個模型同步到介面上的使用方去,整個過程清晰可控。

從協作關係上講,很多前端開發團隊每個成員的職責不是很清晰,有了前端的MV*框架,這個狀況會大有改觀。MV*框架的理念是把前端按照職責分層,每一層都相對比較獨立,有自己的價值,也有各自發揮的餘地。

為什麼多數做網際網路前端開發的同學們感受不到MV*框架的重要性呢,因為在這個協作體系裡,Model的這一塊不夠複雜,在傳統軟體領域,Model的部分是程式碼最多的,View的相對少一些,而網際網路領域裡,基本是相反的,所以Model這塊淪為附加,如果主要在操作View和Controller,那當然jQuery這類框架比較好用了。

所以,經常看到有網際網路產品的同學們講前端MVC,但舉例的時候,都比較牽強,很多時候,他們舉出來的那個Model,其實都不能算真正的Model,而是在操作View的過程中一些輔助的模型,真正的Model是貫穿前後端的。

歸根結底,前端MV*框架帶來的是一整套工作流程的變更,後端工程師也可以編寫前端的模型程式碼,把它跟後端徹底打通,互動工程師處理UI跟模型的互動關係,UI工作人員可以專注、無障礙地處理HTML原始碼,把它們以介面模版的形式提供給互動工程師。這一整套協作機制能夠大大提高B/S架構系統的開發效率,如果再有外圍的管控平臺,生產效率將真正踏進工業化的階段。

到這個階段,前端開發人員的出路是什麼呢?我認為有兩種。拿服裝行業來對比,如果你要的是普通的,就使用工業手段批量生產,使用MV*框架,做好架構和元件重用,做得快,細節不是很講究。如果你想要更好的,有特色的,就需要名家設計,手工打造,非常精巧,高階大氣上檔次。所以,這也就代表著前端開發的兩種發展方向。

相關文章