淺談MVC/MVP/MVVM模式(概述)

本文來自個人博客 這個想法不必定對系列,so,這個想法不必定對😉

一切皆爲數據(0,1),一切皆可量化jquery

無論承不認可,頁面的展現都是數據的可視化。HTML 是數據,CSS 是數據,JS也是數據。只是這些數據的組合最終變成了咱們想要的效果。瀏覽器

最爲直觀的是,咱們在開發者工具 Console 控制檯中,輸入任何形式的數據並點擊 Enter 時,最終會在下方顯示出來(前提是輸入正確的數據類型和格式)。又或者,咱們用某些參數從服務請求一個 JSON 文件,瀏覽器上就會展現文件內容。數據 => 視圖,就是這麼簡單直接。框架

引子

然而,實際上的狀況遠遠比這複雜。爲了更好的視覺享受和用戶體驗,瀏覽器上的頁面效果愈來愈炫,交互邏輯也愈來愈複雜。咱們拿到的第一手數據(或來自用戶,或來自服務)已經不能直接用來展現了,而是要通過相應的邏輯處理(在這裏咱們稱第一手數據爲源數據,通過邏輯處理後的數據稱爲目標數據)。視圖上的數據就是目標數據的映射。mvvm

而處理後的數據又該如何展現呢?是基於 DOM 作操做,仍是基於目標數據從新渲染呢?二者均可,前者是以 jQuery 爲表明,後者則是以 Vue 等新框架爲主。舉個例子🌰,對於某個 DOM 元素的顯隱。ide

< !--jQuery -->
  <div id='jquery'></div>
$('#jquery').hide();

< !--Vue -->
  <div id='jquery' v-show={id[jquery]}></div>
data: {
  id: {
    jquery: fasle
  }
}

基於 DOM 操做, 若是咱們須要對這個 DOM 隨時改變顯隱,就須要不斷操做 DOM 來更改樣式。 若是基於數據操做,咱們只須要更改 jQuery 的值便可。工具

咱們再回到剛纔的話題,對於複雜的交互頁面,數據 => 視圖 的關係已經再也不像以前那麼純淨了。爲了應付複雜的場景,數據視圖 再也不是狹義上的數據和視圖。數據包括了數據和數據相關的操做,視圖包括了視圖和對視圖相關的一些操做。spa

MV*模式

借用MV* 框架模式,這裏的 數據視圖 對應着 ModelView. 簡單點的頁面,Model - View 徹底可以應付過來。可是複雜的場景,ModelView 會分擔太多的邏輯而顯得臃腫,甚至可能包含了不在本身職責範圍內的邏輯。設計

此時咱們就要藉助第三者來協調 ModelView 之間的關係。如何合做,其實也早有了相應的解決方案。好比 MVC、MVP、MVVM。由於重點始終在於協調 ModelView,因此它們統稱爲 MV*code

MVC&MVP.jpg

MVC (Model(模型)-View(視圖)-Controller(控制器)), MVP (Model(模型)-View(視圖)-Presenter(中介者)) 以及 MVVM (Model(模型)-View(視圖)-ViewModel(視圖模型)),是種模式也是種抽象的概念。開發

每一種模式在實踐中可能存在着不一樣的變體,但這不妨礙它們屬於同一個模式。每一種模式的不一樣變體都是爲了解決不一樣問題而產生的,因此它們沒有什麼優劣之分。

如今咱們就把三種模式擬人化來闡述不一樣模式的運做方式。

由四節電池驅動的J-20模型:
J-20.jpg

MVC

公司:飛機模型製造商 => 生產的飛機模型能夠自主塑形。

模式:MVC

飛機模型 V:由模型數據生產出的模型。職責有:由模型數據自主塑形、將收集用戶反饋並轉發。

工程師 M:負責將客服的需求參數轉換成最終的模型數據。職責有:對數據的操做、通知飛機模型更新。

工程師 C:協調 M 和 V。負責響應用戶、調用工程師M生成目標數據。

首先咱們要知道,客戶提出了想要一個 60cm * 60cm 的飛機模型,這個需求到了製造商那裏確定不是給出個 60cm * 60cm 的小方塊,而是根據需求計算處理生產真正的飛機模型(好比什麼樣的造型設計才能最大減小阻力),工程師M的工做之一就是根據原始數據並結合特定的邏輯規則給出最終的模型數據。

如今,用戶手裏有一飛機模型V,不過這個飛機模型的飛機雙翼和用戶想象的不同。因而用戶根據飛機模型上提供的方式反饋了問題(好比飛機模型提供了留言功能,用來收集用戶反饋)。工程師C收到了反饋後,把工程師M拉過來對數據進行處理並生成新的模型數據,並讓工程師M通知到共享相同數據的飛機模型去更新數據自主調整。

插一句,說到調整,咱們有兩種方式。一個是,咱們能夠針對用戶不滿意的地方(飛機雙翼)進行調整。一個是,咱們飛機模型格式化按照最新的數據模型從新初始化一下。前者能夠認爲就是基於 DOM 操做的方式,後者就是基於數據的處理方式。

在 MVC 中,Model 和 View 之間耦合,視圖的更新須要 Model 去直接通知。Model 內由於有 View 的引用才能讓視圖更新。

MVC.png

MVP

若是 Model 只想作數據相關的操做,把通知 View 的邏輯挪到了 Control 裏,這時 Control 搖身一變稱爲了 Presenter。由於解耦了 Model 和 View,也使得它們的職責劃分更加清晰。

公司:飛機模型製造商 => 生產的飛機模型能夠自主塑形。

模式:MVP

飛機模型 V:由模型數據生產出的模型。職責有:由模型數據自主塑形、將收集用戶反饋並轉發。

工程師 M:負責將客服的需求參數轉換成最終的模型數據。職責有:對數據的操做。

工程師 P:協調 M 和 V。負責響應用戶、調用工程師M生成目標數據、更新視圖。

在 MVP 模式中,工程師M的工做專一於數據,通知的活甩給了工程師P。
和 MVC 一樣的場景,工程師P接到反饋後,把工程師M拉過來處理了數據,而後又讓飛機模型依據已經處理後的數據自主調整。每次數據的變化都要主動去通知視圖更新。

MVP.png

MVVM

若是數據變化可以自主觸發視圖更新,對 Presenter 來講也會輕鬆很多。因而 Presenter 再次搖身一變 稱爲了 ViewModel。

公司:飛機模型製造商 => 生產的飛機模型能夠自主塑形。

模式:MVVM

飛機模型 V:由模型數據生產出的模型。職責有:由模型數據自主塑形、將收集用戶反饋並轉發。

工程師 M:負責將客服的需求參數轉換成最終的模型數據。職責有:對數據的操做。

工程師 VM:協調 M 和 V。負責響應用戶、調用工程師M生成目標數據並更新視圖。

MVVM.png

在 MVVM 中,View 和 Model 的變化彷佛不大。爲了在數據變化後可以自動更新視圖,ViewModel 進行了所謂的數據綁定。ViewModel 將 目標數據 和視圖進行了綁定,在最終生成目標數據時,會觸發視圖的更新。

在這裏咱們能夠想象有兩份數據,一份是源數據,一份是目標數據。綁定視圖的是目標數據,這樣,咱們直接修改目標數據時會觸發視圖更新。若是是源數據經處理後賦給目標數據,目標數據也會改變,也會觸發試圖更新。

總之,在 MVVM 中,視圖是目標數據的可視化,經過改變視圖裏的數據也就等於改變了目標數據。

和 MVC、MVP 一樣的場景,不過科技發達了,工程師VM有個自動化處理程序。用戶反饋了問題,工程師VM的這個自動處理程序接到反饋自動處理並將結果發給飛機模型讓其自主調整。

如下是Vue的MVVM示意圖:
mvvmVue.png
MVC、MVP和MVVM大體就是如此,根據三種模式以及不一樣場景,最終演變出了不一樣的變體。

可是,不一樣的變體是針對不一樣問題的解決方案,指不定後來還會有 MVA、MVB..., 誰知道呢

相關文章
相關標籤/搜索