AngularJS 究根到底是 MVC 還是 MVVM?


其實這並不重要,你完全可以拿 angular 當 view 層和 backbone/flux 混著用。

對於一個框架,只要搞清楚一個核心主題就行了。angular 的核心主題是把模板轉譯成一個帶有內部狀態管理的 renderer,react 的核心主題是把 jsx 轉譯成一個也帶有內部狀態,但是管理功能比較弱的 renderer。這樣做的價值在於模板也好,jsx 也好,都是聲明語法,從開發成本的角度,聲明編碼是優於邏輯編碼的。

至於 model 放在哪裡,是 mvvm 還是 mvc,其實是實現細節。angular 狀態管理的功能比較強,所以能容納一些業務邏輯的數據流,react 狀態管理比較弱,所以更適合做貧血組件,把數據流單獨拿出來放到各種 flux 里去。

區別就這點,其實不是什麼本質區別。前端框架和後端框架最大的區別在於事件流,後端的事件因為是 http 請求,所以往往通過一個非常明顯的 controller 入口統一處理,但是前端的事件來自於 gui 操作,所以 controller 就被打散了,根據 controller 組織方式的不同,衍生出來各種 mv*,其實說到底,都是一個東西。


MVW

W for Whatever


這個問題很有意思

angular 官方的解釋是 MVW (Model-View-Whatever) docs(README.md): add purpose section · angular/angular.js@cff232a · GitHub

但是注意了,這段 commit 產生於 2016年2月8號,也就是說官方在很晚的時間點才統一口徑(之前官方文檔有的地方說是 MVVM,有的地方說 MVW)。

所以可以發現,ng1 的維護者們也意識到,直接宣傳 ng1 是 MVVM 不符合術語定義的。

從 ng1 官方給出的 tutorial 的各種 demo 和 code snippets 來看,準確來說 ng1 應該是 VW (View-Whatever)模式,沒錯你看不到 M 跟 VM。

為什麼這麼說?

從官方 api doc 摘來的定義:

  • Model — Models are the properties of a scope; scopes are attached to the DOM where scope properties are accessed through bindings.

  • Controller — The ngController directive specifies a Controller class; the class contains business logic behind the application to decorate the scope with functions and values

官方定義的 Model 跟 Controller(可以視作 ViewModel) 的職責不僅與標準術語定義相去甚遠,甚至還有職責重疊的部分。

所以從模式術語的定義來看,ng1 最多只能說是 VW 模式。。

關於 MVVM 模式的標準定義,可以看我這篇的翻譯:https://github.com/kuitos/kuitos.github.io/issues/35


比較傾向MVVM。


在看薦前端分類中有提到框架模式,框架模式不是一門寫代碼的學問,而是一門管理與組織代碼的學問。其本質是一種軟體開發的模型。與設計模式不同,設計模式是在解決一類問題時總結抽象出的公共方法(工廠模式,適配器模式,單例模式,觀察者模式 。。。 。。。),他們與某種具體的技術棧無關。一種框架模式往往使用了多種設計模式,切不要把他們的關係搞混。

不管是 mvc 還是 mvp 或 mvvm ,他們都是 數據驅動 的。核心上基於 m 推送消息,v或p來訂閱 這個模型。使用者需要維護的不再是 UI 樹,而是抽象的數據。(通過數據,可以隨時構建出新的 UI 樹), 當 UI 的狀態一旦多起來,這種框架模式的優勢便體現出來了。 因為維護數據可比維護 UI 狀態爽多了。


隨便搜了一下 AngularJS是 MVW pattern: Model View Whatever— whatever works for you.

比較犯懶 來粘個原po 在Jul 19, 2012發在google circle的帖:

MVC vs MVVM vs MVP. What a controversial topic that many developers can spend hours and hours debating and arguing about.

For several years AngularJS was closer to MVC (or rather one of its client-side variants), but over time and thanks to many refactorings and api improvements, it"s now closer to MVVM – the $scopeobject could be considered the ViewModel that is being decorated by a function that we call a Controller.

Being able to categorize a framework and put it into one of the MV* buckets has some advantages. It can help developers get more comfortable with its apis by making it easier to create a mental model that represents the application that is being built with the framework. It can also help to establish terminology that is used by developers.

Having said, I"d rather see developers build kick-ass apps that are well-designed and follow separation of concerns, than see them waste time arguing about MV* nonsense. And for this reason, I hereby declare AngularJS to be MVW framework - Model-View-Whatever. Where Whatever stands for "whatever works for you".

Angular gives you a lot of flexibility to nicely separate presentation logic from business logic and presentation state. Please use it fuel your productivity and application maintainability rather than heated discussions about things that at the end of the day don"t matter that much.


首先為什麼我們會需要MVC?因為隨著代碼規模越來越大,切分職責是大勢所趨,還有為了後期維護方便,修改一塊功能不影響其他功能。還有為了復用,因為很多邏輯是一樣的。而MVC只是手段,終極目標是模塊化和復用。

在MVC原始報告中指出:view永遠不會知道用戶輸入,比如滑鼠操作和按鍵。很顯然,在Web前端,你無法做到這一點

John Gossman(WPF的架構師)在他的文章中提到,Model/View/ViewModel中的View表示可見元素,按鈕,窗體,圖形或者GUI中更複雜的控制項,它會對快捷鍵進行編碼

AngularJS是一款開源的谷歌出品的JavaScript MV*(MVW、MVVM、MVC)框架,早期的四大MVVM框架有angularjs(谷歌公司),emberjs(蘋果公司),knockoutjs,winjs(後兩個均是微軟出品)

mvc的界面和邏輯關聯緊密,數據直接從資料庫讀取。mvvm的界面與viewmode是松耦合,界面數據從viewmodel中獲取。

所以,angularjs是更適合於MVVM。


推薦閱讀:

前端是如何管理後端提供的API的?
如何使自己編寫的程序更靠譜(Robust)?
js原型鏈與lua元表的異同?
產品經理如何在設計產品時避免給開發挖坑?

TAG:前端開發 | JavaScript | MVC | 前端開發框架和庫 | AngularJS |