vue 設計模式之 MVC、MVP 和 MVVM 三種設計模式的異同

MVC、MVVM、MVP 是常見的設計模式,也是常見的設計思想,那它們之間有什麼區別呢?接下來對它們進行簡要的歸納總結

三種模式的介紹

1.MVC:經典設計模式

MVC 全名爲 Model View Controller ,是模型(Model)- 視圖(View)- 控制器(Controller)的縮寫。他是 1970 年代被引入到軟件設計大衆的。MVC 模式致力於關注點的切分,這意味着 model 和 controller 的邏輯是不與用戶界面(View)掛鉤的。因此,維護和測試程序變得更加簡單容易。

標準 MVC 工作模式: 當有用戶的行爲觸發操作時,控制器(Controller)更新模型,並通知視圖(V)和模型(M)更新,這時視圖(V)就會向模型(M)請求新的數據,這就是標準 MVC 模式下 Model,View 和 Controller 之間的協作方式。

MVC 優點:

  1. 耦合性低,視圖層和業務層分離,這樣就允許更改視圖層代碼而不用重新編譯模型和控制器代碼;

  2. 重用性高;

  3. 生命週期成本低;

  4. MVC 使開發和維護用戶接口的技術含量降低;

  5. 可維護性高,分離視圖層和業務邏輯層也使得 WEB 應用更易於維護和修改;

  6. 部署快。

MVC 缺點:

  1. 不適合小型,中等規模的應用程序,花費大量時間將 MVC 應用到規模並不是很大的應用程序通常會得不償失。

  2. 視圖與控制器間過於緊密連接,視圖與控制器是相互分離,但卻是聯繫緊密的部件,視圖沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。

  3. 視圖對模型數據的低效率訪問,依據模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數據。對未變化數據的不必要的頻繁訪問,也將損害操作性能。

2.MVP:MVP 模式將 Controller 改名爲 Presenter,同時改變了通信方向。

MVP 全名爲 Model View Presenter ,是由 MVC 演變而來,它和 MVC 的相同之處在於:Controller / Presente 都是負責業務邏輯,Model 管理數據,View 負責顯示。不過在 MVP 中 View 並不直接與 Model 交互,它們之間的通信是通過 Presenter (MVC 中的 Controller) 來進行的,即使用 Presenter 對視圖和模型進行了解耦,讓它們彼此都對對方一無所知,溝通都通過 Presenter 進行。

標準 MVP 工作模式: 在 MVP 中,Presenter 可以理解爲鬆散的控制器,其中包含了視圖的 UI 業務邏輯,所有從視圖發出的事件,都會通過代理給 Presenter 進行處理;同時,Presenter 也通過視圖暴露的接口與其進行通信。

MVP 特點:

  1. M、V、P 之間雙向通信。

  2. View 與 Model 不通信,都通過 Presenter 傳遞。Presenter 完全把 Model 和 View 進行了分離,主要的程序邏輯在 Presenter 裏實現。

  3. View 非常薄,不部署任何業務邏輯,稱爲” 被動視圖”(Passive View),即沒有任何主動性,而 Presenter 非常厚,所有邏輯都部署在那裏。

  4. Presenter 與具體的 View 是沒有直接關聯的,而是通過定義好的接口進行交互,從而使得在變更 View 時候可以保持 Presenter 的不變,這樣就可以重用。不僅如此,還可以編寫測試用的 View,模擬用戶的各種操作,從而實現對 Presenter 的測試–從而不需要使用自動化的測試工具。

MVP 優點:

  1. 模型與視圖完全分離,我們可以修改視圖而不影響模型;

  2. 可以更高效地使用模型,因爲所有的交互都發生在一個地方——Presenter 內部;

  3. 我們可以將一個 Presenter 用於多個視圖,而不需要改變 Presenter 的邏輯。這個特性非常的有用,因爲視圖的變化總是比模型的變化頻繁;

  4. 如果我們把邏輯放在 Presenter 中,那麼我們就可以脫離用戶接口來測試這些邏輯(單元測試)。

MVP 缺點:視圖和 Presenter 的交互會過於頻繁,使得他們的聯繫過於緊密。也就是說,一旦視圖變更了,presenter 也要變更。

3.MVVM

MVVM 全名爲 Model View ViewModel。這個模式提供對 View 和 View Model 的雙向數據綁定。這使得 View Model 的狀態改變可以自動傳遞給 View。典型的情況是,View Model 通過使用 obsever 模式(觀察者模式)來將 View Model 的變化通知給 model。

MVVM 模式關鍵點:

  1. 用戶和 View 交互。

  2. View 和 ViewModel 是多對一關係。意味着一個 ViewModel 只映射多個 View。

  3. View 持有 ViewModel 的引用,但是 ViewModel 沒有任何 View 的信息。

  4. View 和 ViewModel 之間有雙向數據綁定關係。

MVVM 優點:

  1. 低耦合,視圖(View)可以獨立於 Model 變化和修改,一個 ViewModel 可以綁定到不同的”View” 上,當 View 變化的時候 Model 可以不變,當 Model 變化的時候 View 也可以不變。

  2. 可重用性,可以把一些視圖邏輯放在一個 ViewModel 裏面,讓很多 view 重用這段視圖邏輯。

  3. 獨立開發,開發人員可以專注於業務邏輯和數據的開發(ViewModel),設計人員可以專注於頁面設計,使用 Expression Blend 可以很容易設計界面並生成 xml 代碼。

  4. 可測試,界面向來是比較難於測試的,而現在測試可以針對 ViewModel 來寫。

三種模式的區別

MVC 是世界上最低級、最原始的 UI 模式;MVC 就是在 V 上綁定 M,然後 C 負責處理界面整個提交請求,並且一遍遍地刷新整個 V。這種機制。所以 MVC 的標誌是 “初級、單向綁定、一遍遍刷新 UI”。

MVP 則是深入到程序的 “骨髓”,UI 設計模板與 MVP 事件定義綁定,讓程序員可以捕獲這麼一個組件的豐富的事件,然後在事件處理過程中又去從控件樹上去直接訪問其它所有控件,直接修改其屬性。開發的精力很大程度上用在學習各種控件的內部機制上,學習曲線陡峭。所以 MVP 的標誌是 “複雜、事件驅動、精細到每一個控件層次”。

MVVM 則是在 MVP 上的改進,它隔離了控件操作層,UI 模板上各種控件直接跟 VM 層的屬性綁定,使得 VM 屬性改變時自動更新 UI 控件,反之 UI 控件的值改變時又自動更新 VM 屬性。這樣編程的方式就不是去一大堆控件事件處理,而是寫少量的 VM 屬性更改行爲代碼。開發精力絕大部分都放在業務與 UI 的綁定上,而並不需要研究控件內部機制。

三種設計模式的應用

1.MVC 模式。

React 使用的是 MVC 模式。所有 MVC 框架都是單向數據流的。
特色:

注:react 實際上是一個 “僞 MVC”,它其實是 MVP 的,但是它深知 MVP 模式的弊病,它明明是基於組件並且綁定了組件的 change 事件的,但是它有使用虛擬 DOM 的方式來一遍遍刷新 UI 控件(並且爲了解決性能問題,有各種負責和詭異的避免全局刷新 UI 樹的反模式操作)。所以雖然 React 自稱爲 MVC 模式,但是實際上它是 MVP 的變種。

2.MVP 模式。

JQuery 是非常經典的 MVP 編程模式

3.MVVM 模式。

Knockout、AngularJS、Vue 等可以看作是 MVVM 模式

Angular 使用的 MVVM 模式。當觸發 UI 事件,ajax 請求或者 timeout 延遲,會觸發檢查。這時會調用 $digest 循環遍歷所有的 listener 裏的數據,判斷當前值是否和先前的值有區別,如果檢測到變化的話,會調用 $watch 函數,最後把所有的變化全部更新,調用 apply() 方法把新的數據渲染到頁面上。
優點:一次檢測會收集所有的數據變化,然後統一更新 UI,大大減少了操作 DOM 的次數。
缺點:只要有 ui 或 ajax 或 settimeout 操作時就會進行檢查,且當 watcher 之間相互影響的時候,更會觸發多次 $digest 循環,這樣 watcher 一多,就會很影響性能。

注:AngularJS 其實在 MVVM 上做的不是很好,傾向於 MVP。只有 Knockout 是實現了經典的 MVVM 設計模式,而且有幾個性能相關的特性(例如自動延遲 UI 刷新、自動抽稀無用的 UI 刷新操作)可以將性能提高(相對於其它許多 web 前端框架)至少幾十倍。

Vue 一定意義上算是 React 和 Angular 的集大成者。它吸取了 MVVM 的數據管理思想,同時應用了 React 的 virtual Dom 算法。它使用了雙向數據綁定來滿足開發的便捷,但是它不同組件之間又使用單向數據流,來保證數據的可控性。它使用了很多 Angular 的指令語法,但是它革新了 Angular 的髒數據檢查機制,使用數據劫持的方法來觸發數據檢查機制。它借鑑了 React 的組件化思想,大大增加了前端工程的結構規範化。

注:Vue 內部使用了 Object.defineProperty() 來實現雙向綁定,通過這個函數可以監聽到 set 和 get 的事件。

總結

MVC 只是把控件跟 M 綁定,一遍遍刷新 UI。而 MVP 則是把控件跟事件單向綁定,它的假設是程序員最愛寫低級的代碼來操作控件。而 MVVM 則是把控件跟 VM 雙向綁定,它的假設是交互界面設計時最愛寫高層次一些的聲明來操作用戶業務行爲上的變化。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/80XSCLTwsJgWvXOEs-GXUA