參考:
MVC,MVP 和 MVVM 的圖示 - 阮一峯
http://www.ruanyifeng.com/blo...
Web開發的MVVM模式
http://www.cnblogs.com/dxy198...
界面之下:還原真實的MV*模式
https://segmentfault.com/a/11...
Angular沉思錄(一)數據綁定
https://github.com/xufei/blog...
深刻理解JavaScript系列(32):設計模式之觀察者模式
http://www.cnblogs.com/TomXu/...javascript
MVC/MVP/MVVM 在不少博問中都有整理,這裏我根據閱讀博文和本身的理解,梳理一下 web 前端 html、css、javascript 中的他們。css
用戶行爲輸入,View 傳遞給 Controller(在JS中經過事件監聽實現);Controller 進行應用邏輯處理,調用 Model 暴露的接口方法操做 Model;View 與 Model 間爲觀察者模式,Model 更新完數據後通知 View 更新。html
JS中的觀察者模式 - 湯姆大叔博文,本文闡述瞭如何在JS中實現觀察者模式:觀察者模式中 Model 通知 View 更新,其實是 Model 對訂閱了本身的 View 提供操做方法的調用。前端
View,View 包含2部分:1)實現界面展現的 html+css;2)對外暴露的操做 View 的方法。
View -> Controller,用戶行爲從視圖傳遞至控制器,有兩種方法:1)經過 html 標籤的事件屬性如 onclick;2)JS中的addEventListener(非IE)/ attachEvent(IE)方法。(如JQuery的bind和angular的ng-click等都是對原生方法的封裝,等效於上述方法)
Controller,當視圖發生用戶行爲輸入時候,會進入控制器中的事件回調函數,在回調函數中,通常會對界面數據進行預處理(如:輸入校驗)、應用邏輯處理(如:界面顯示Loading),而後調用對應的 Model 方法進行模型更新操做。
Controller -> Model,Controller 的事件回調函數中調用 Model 的操做方法。
Model,Model 可理解爲一個對象,對象的屬性就是抽象的數據模型,對象的方法就是對 Controller 暴露的操做方法。
Model -> View,Model 更新 View 使用觀察者模式,從JS實現上來講 Model 有個數組隊列中保存着訂閱(subscribe)了本身 View 的更新方法,Model 更新完畢後,遍歷並調用數組中的 View 更新方法即爲發佈(publish)。java
OK,這就是 HTML+CSS+JS 實現 經典MVC 的一個流程,下面咱們說說它的優缺點。git
優勢:
1)職責分離思想,MVC三者各司其職,模塊化;
2)觀察者模式,實現單個Model可更新多視圖更新。github
職責分離的優勢不用多說,代碼清晰易維護;觀察者模式實現單個數據模型,可同時更新多個視圖,擴展性良好。web
缺點:
1)View依賴Model,不可避免引入業務邏輯,不易複用。segmentfault
舉個栗子,model 和 view 以下:
設計模式
model 僅有 good/middle/bad 3種數據,view 基於此數據,需擴展顏色、圖例描述等系列業務邏輯,經典MVC中,view 對外暴露渲染餅圖的方法,顏色這些業務的東東就被包含進去了,這就是咱們說的不可避免引入業務邏輯。假設如今有新的 model2 含3種商品數量(顏色用黃、綠、藍),要複用餅圖 view,咱們很容易想到,在 view 與 model 間加一層模型轉換就能很實現複用,可是經典MVC中,model 與 view 之間是觀察者模式,那麼模型轉換隻能放到 view 中(model 通常不變),view 得擴展個新方法來知足 model2。
這個簡單例子也許不能很充分說明 View 依賴 Model 形成的問題,但可設想若是 View 的業務邏輯和應用功能十分複雜,那麼要適配不一樣的Model必然形成 View 的臃腫,必定程度後便難以複用。
我理解,如今你們常說起的 MVC 實際就是 MVP,它刷新界面通常遵循 V -> P -> M -> P -> V 的步驟。(MVP 模式將 Controller 更名爲 Presenter,可等同視之)
用戶行爲輸入,View 傳遞給 Presenter(在JS中經過事件監聽實現);Presenter 進行應用邏輯處理,調用 Model 暴露的接口方法操做 Model;Model 更新完數據後傳遞給 Presenter(異步 Model 操做可以使用 promise,讓Presenter在回調函數中得到最新數據),Presenter 處理最新數據,調用 View 暴露的接口方法更新 View。
MVP 完全分離了 View 與 Model,使用 HTML+CSS+JS 編碼,移除 MVC 觀察者模式,其他都很容易理解,在此再也不贅述。
優勢:
1)解決View與Model耦合問題,使View變薄,更易複用。
請對應參考上面 MVC 中的缺點1的例子。使用 MVP 後,Presenter 做爲 View 和 Model 的中間層,那麼 View 和 Model 僅需對外暴露標準接口,模型轉換的那些事兒,所有能夠交給Presenter,View 層變薄,更容易複用。
缺點:
1)Presenter 承擔了V->M和M->V的應用和業務邏輯,容易變得臃腫,可維護性下降。
MVVM 模式實際就是將 MVP 中的 Presenter 更名爲 ViewModel,調用過程基本一致,最大的改良是 ViewModel 間的雙向綁定。
這裏以實際項目中用過的 Angular1.x 爲例,下圖僅爲示意便於理解。
View 和 ViewModel 間,有一個對象 $scope,ViewModel 能夠操做修改 $scope.data,View html 使用 $scope.data。當 ViewModel 設置 $scope.data=123 時,Angular框架會自動刷新 View 的顯示 123,同理當界面有 input 這樣的入口時,修改 data 時,Angular框架也會自動刷新到 $scope.data 中。【優勢】View 和 ViewModel 間的數據同步功能,部分被 Angular 框架承擔,部分解決了 MVP 中 Presenter 臃腫的問題,固然編碼也會很方便。