首頁技術(shù)文章正文

前端培訓之淺談框架模式(MVC MVP MVVM)(二)

更新時間:2017-05-17 來源:黑馬程序員web前端培訓學院 瀏覽量:

三代目: M-V-C:(模型,視圖,控制器)


現(xiàn)在網(wǎng)上有很多關(guān)于mvc的介紹,讓人糾結(jié)的是他們各不相同,而且有的根本就說的不對, 對于框架模式這東西,沒有一個嚴格的規(guī)定說這樣搞是 mvc 那樣就不是。 甚至連mvc本身也有很多變種,我們只要從根源上理解這個東西就行。
我就不扒祖墳了,咱們只需要知道它已經(jīng)存在了 30多年就行了。
我們思考一下 UI(圖形化用戶界面) 的本質(zhì):
為什么要有UI, 在計算機眼中 一切即數(shù)據(jù),其實要是深挖這個問題,數(shù)據(jù)與操作其實都是 0 1 組成的機器碼,只不過 CPU運行的時候用指定寄存器的數(shù)據(jù)當做指令罷了,也就是說決定一個數(shù)據(jù)到底是數(shù)據(jù)還是指令 只取決于他所在的寄存器位置。(好了好了 扯遠了,往回跑。。) 數(shù)據(jù)的操作是抽象的,是專業(yè)人士干的事情, 計算機為了走進千家萬戶, 必須提供一種傻瓜式的操作方式,于是UI誕生了。。。 用一句話解釋UI就是:他是數(shù)據(jù)到圖像的一種映射程序;
剛才說了它是一種映射程序,用戶通過操作圖像上的按鈕,來達到操作數(shù)據(jù)的目的,數(shù)據(jù)被用戶改變后,肯定需要從新生成映射。
請允許我向上一張老掉牙的圖:

說說這里面 Modle View Controller 是干什么的:
1.View: 放置視圖相關(guān)的代碼,原則上里面不應該有任何業(yè)務邏輯。
2.Controller: 放置視圖與模型之間的映射,原則上這里應該很薄,他只放一些事件綁定相關(guān)的代碼(router),但并不實現(xiàn)真正的功能,他只是一個橋梁。
3.Modle: 這里的modle不是說 實體類, 他是主要實現(xiàn)邏輯的地方。
那還是上面 買水果的例子,那么在MVC下該如何設(shè)計呢:
概念 解釋
view 放置界面代碼,以及一些刷新邏輯 如數(shù)據(jù)中的 0 1 轉(zhuǎn)成 男 女
controller 放置一些綁定邏輯。完成router,不實現(xiàn)函數(shù)體。
model 接收view的注冊,當自身數(shù)據(jù)變化時,執(zhí)行view的刷新函數(shù)。 業(yè)務邏輯都在這里
他是這樣一個流程:
1.創(chuàng)建顯示蘋果數(shù)量的控件。
2.將上面控件注冊到model中。(設(shè)置關(guān)聯(lián)的數(shù)據(jù),–蘋果數(shù)變量)
3.修改model中 蘋果數(shù)變量 。
4.由于蘋果數(shù)變量被修改,觸發(fā)所有綁定在上面的控件(view)從新執(zhí)行刷新函數(shù)。
5.顯示蘋果數(shù)量的控件被更新。
這樣便解決了大部分界面與邏輯耦合的問題,但是它并不完美:
View 和 Model 并不是完全脫離的,還是有一些邏輯耦合,因為需要根據(jù)修改后的model從新刷新view。 難免view里面沾染一點model的結(jié)構(gòu)。
代碼量膨脹。
不方便進行更精細的顆?;刂?。(因為view只知道 model被改了,但不知道誰改的!)
  1. model在對應多個view的時候,很難都伺候到位。
于是。。。

四代目: M-V-P:(模型,視圖,派發(fā)器)


請允許我再上一張老圖:

針對mvc的一些問題,在mvp模式下, 斬斷了 view 與 model的關(guān)系, 當m 改變時,m 通知 p 去改變v, 所以v變得更純潔(刷新邏輯被移動到了p層), 為了保證m可以最大程度的復用 一部分業(yè)務邏輯也從 m 轉(zhuǎn)移到了p所以 mvp下 p 非常厚實。
mvp中最后改變v的是p那么在 v與p 之間會有一個接口,解決怎么轉(zhuǎn)換以及傳值的問題。

五代目: M-V-VM:(模型,視圖,抽象視圖)

MVVM,最早來自于微軟社區(qū),用于WPF

Model-View-ViewModel的關(guān)系圖:

mvvm 與 mvp 的最大區(qū)別就是它使用 數(shù)據(jù)綁定(Data Binding)、依賴屬性(Dependency Property)、命令(Command)、路由事件(Routed Event) 來搞定與view層的交互, 但是這種綁定是與某種具體技術(shù)棧相關(guān)的, ViewModel從Model中抽象而來,但更貼近于業(yè)務模型, 比如你Model中某字段是 true false, ViewModel中可能就是 “黑”,”白”等 這種更貼近業(yè)務場景的描述。 ViewModel中的屬性直接與某具體控件的屬性相綁定。 也就是說當某具體控件發(fā)生變化,ViewModel中的 某個字段就會跟著變化,然后Model中的字段也會進一步變化。

以上述為例:
用戶使用UI修改了性別字段:
1.操作觸發(fā)綁定在UI上的事件(Data Binding 自動完成)
2.事件進入vm層,根據(jù)綁定規(guī)則,找出對應的vm字段, (如表示性別的組件綁定的是vm中的sex字段)
3.vm上的sex被設(shè)置成true,(view層上值為”男” “女”,但是在抽象的vm層中我們用 bool 來表示這個字段)
4.同理尋找m層上的對應字段,m上的sex被vm修改成1
5.m找到所有與sex字段有綁定關(guān)系的vm通知他們更新。
6.所有接到通知的vm更新sex字段。
7.vm尋找所有與sex字段有綁定關(guān)系的view層控件,通知他們更新(Data Binding 自動完成)。
8.view被更新。所有涉及到sex字段的組件都被刷新。
有時候這個流程未必是從 1 步開始,如果直接對 m 進行修改,則就是從第 4 步開始的。
同理如果沒有view層,則沒有必要進行 7 , 8步驟。
這就是說 mvvm 下可以完全干掉 view 層, 方便的進行自動化測試。

小結(jié) (推送/訂閱 這個是數(shù)據(jù)驅(qū)動的核心)

不管是 mvc 還是 mvp 或 mvvm ,他們都是 數(shù)據(jù)驅(qū)動 的。核心上基于 m 推送消息,v或p來訂閱 這個模型。使用者需要維護的不再是 UI 樹,而是抽象的數(shù)據(jù)。(通過數(shù)據(jù),可以隨時構(gòu)建出新的 UI 樹), 當 UI 的狀態(tài)一旦多起來,這種框架模式的優(yōu)勢便體現(xiàn)出來了。 因為維護數(shù)據(jù)可比維護 UI 狀態(tài)爽多了。
前端中的mvc:
并不是說 m v c 三者一定要獨立出現(xiàn)才行,比如 Backbone。js 它的 controller 層只是一個 router。 其實在傳統(tǒng) mvc 中 controller 里本來就沒有太多的邏輯,他只是一個事件的”傳遞者”, 加之 javascript 中人們習慣使用匿名函數(shù)當事件回調(diào),這樣就等于直接在 view 層中把功能函數(shù)實現(xiàn)了。 所以 view 與 controller 合并 或者 controller 與model 合并都有可能。
 
JavaScript

1
2
3
$(xxx).click(function(e){
    console.log(e);
})

本文版權(quán)歸黑馬程序員web前端開發(fā)學院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處,謝謝!
作者:黑馬程序員web前端培訓學院;
首發(fā):http://pantone-color.com.cn/news/web.html

分享到:
在線咨詢 我要報名
和我們在線交談!