複雜的軟件必須有清晰合理的架構,不然沒法開發和維護。前端
MVC(Model-View-Controller)是最多見的軟件架構之一,業界有着普遍應用。它自己很容易理解,可是要講清楚,它與衍生的 MVP 和 MVVM 架構的區別就不容易了。java
昨天晚上,我讀了《Scaling Isomorphic Javascript Code》,忽然意識到,它們的區別很是簡單。我用幾段話,就能夠說清。node
(題圖:攝於瓦倫西亞,西班牙,2014年8月)react
1、MVC
MVC模式的意思是,軟件能夠分紅三個部分。android
- 視圖(View):用戶界面。
- 控制器(Controller):業務邏輯
- 模型(Model):數據保存
各部分之間的通訊方式以下。ios
- View 傳送指令到 Controller
- Controller 完成業務邏輯後,要求 Model 改變狀態
- Model 將新的數據發送到 View,用戶獲得反饋
全部通訊都是單向的。git
2、互動模式
接受用戶指令時,MVC 能夠分紅兩種方式。一種是經過 View 接受指令,傳遞給 Controller。
另外一種是直接經過controller接受指令。
3、實例:Backbone
實際項目每每採用更靈活的方式,以 Backbone.js 爲例。
1. 用戶能夠向 View 發送指令(DOM 事件),再由 View 直接要求 Model 改變狀態。
2. 用戶也能夠直接向 Controller 發送指令(改變 URL 觸發 hashChange 事件),再由 Controller 發送給 View。
3. Controller 很是薄,只起到路由的做用,而 View 很是厚,業務邏輯都部署在 View。因此,Backbone 索性取消了 Controller,只保留一個 Router(路由器) 。
4、MVP
MVP 模式將 Controller 更名爲 Presenter,同時改變了通訊方向。
1. 各部分之間的通訊,都是雙向的。
2. View 與 Model 不發生聯繫,都經過 Presenter 傳遞。
3. View 很是薄,不部署任何業務邏輯,稱爲"被動視圖"(Passive View),即沒有任何主動性,而 Presenter很是厚,全部邏輯都部署在那裏。
5、MVVM
MVVM 模式將 Presenter 更名爲 ViewModel,基本上與 MVP 模式徹底一致。
惟一的區別是,它採用雙向綁定(data-binding):View的變更,自動反映在 ViewModel,反之亦然。Angular 和Ember 都採用這種模式。
(完)
SSY 說:
原來我一直作的是MVP呀
2015年2月 1日 11:57 | # | 引用
Simba 說:
很好。寫的不錯。
2015年2月 1日 11:58 | # | 引用
Ricter 說:
這麼說來 Django 好像是一個 MVP 框架的樣子了…
2015年2月 1日 12:50 | # | 引用
dreamers.yzy 說:
MVC是單向的?不是V->C->M -> C -> V 嗎?
2015年2月 1日 13:01 | # | 引用
Welkin 說:
清晰易懂
2015年2月 1日 15:51 | # | 引用
Milkman 說:
簡明,真知灼見;不像市面上不少文章那般說一揉二,摻雜一塊兒弄得複雜方顯高深,骨架連肉一塊兒亂燉,反致初學者雲裏霧裏。
2015年2月 1日 16:16 | # | 引用
Benja 說:
跟馬老師說的不同,阮老師肯定嗎?
附上:
PoEAA - http://martinfowler.com/eaaCatalog/modelViewController.html
MSDN - https://msdn.microsoft.com/en-us/library/ff649643.aspx
2015年2月 1日 16:18 | # | 引用
kuangyuang 說:
看這篇文章可能更容易理解:http://objccn.io/issue-13-1/
2015年2月 1日 16:57 | # | 引用
xiaorong61 說:
要是再談談最近流行的 flux react 就行了
2015年2月 1日 17:28 | # | 引用
Nancy 說:
同問,有點不是很理解爲何是單向的呢?
2015年2月 1日 18:10 | # | 引用
end-e 說:
我所瞭解到的狀況也是v-c-m-c-v這個流程。。
2015年2月 1日 21:22 | # | 引用
wittyfox 說:
在微博你純屬測試爲知筆記功能 @mywiz,打開爲知筆記果真看到了,看完了以後來這裏頂一下。
正好這三個模式我都認識,^_^。我是自學 Rails 的,Rails 就是 MVC 的,剛開始學 Rails 時,把邏輯都放進了 Views 裏,雖然 Rails 提供了 Helper,可是感受不 OO,就沒用。後來發現 Views 邏輯太多了,而想對網站外觀進行修改時就很費力,放進 Model 中的話,在 Model 中生成 URL 等就很複雜了,須要包含各類 Rails Helper。後來發現了 Github 上的 Presenter,就是把不知道該放進 View 仍是 Model 的東西放進去,View 中再也不與 Model 交互,今天才知道這叫 MVP。MVVM 是我看的 Rails 做者的一篇文章中寫得,英文很差,當時看個大概,沒怎麼明白,今天才明白了。 >_
2015年2月 1日 23:58 | # | 引用
Joshua 說:
MVC在bs架構和cs架構上差異很大,即便同是bs,由於使用的技術的差異,業務的差異,架構的差異,MVC的通訊方式也會和原來你書本上看到的不同。就像backbonejs和angularjs的出現,是發明仍是延伸,仍是糟蹋?天天和它一塊兒工做的人才知道。
全部的設計應該以貼近天然或接近天然規律爲目標。再通俗的講,用的舒服就是天然。好的東西絕對不須要強記一堆原理來理解的。
2015年2月 2日 10:35 | # | 引用
andong777 說:
是的,我理解的MVC也是這個流程的……
2015年2月 2日 17:01 | # | 引用
Tardis0127 說:
iOS開發中大部分使用的MVC和阮兄說的MVP同樣... 有些人也會作成MVVM
2015年2月 3日 02:29 | # | 引用
KILLVIN_LIU 說:
這裏的MVP, MVVM甚至MXXX都只是MVC的變體而已,至於將重點放在C點仍是V點(沒人會但願放到M點吧?!)就天然引出了若干種所謂的模式,其實模式只有一種,你稱爲P也好VM也好,它都只是C的實例而已。老是設法弄出一些所謂的Business Word的傢伙們,是前端開發最大的敵人!
2015年2月 3日 11:32 | # | 引用
Tardis0127 說:
真的不同... 雖然同源, 可是實踐起來效果是不同的... 簡潔清晰高效的構架不是程序員的畢生追求嗎?
2015年2月 3日 13:39 | # | 引用
fastzhong 說:
寫得很好。另外提一句,我是計算機背景,老程序員了,對於那些說什麼你錯誤不少,我能夠負責任地說,把本身的理解和想法寫出來,你比大多數人水平高不少了,但確定有些不完善的地方,你們能夠討論一塊兒進步,這是重點,由於你沒有錯誤不少!
2015年2月 4日 10:59 | # | 引用
kidd 說:
以爲沒法理解「雙向綁定」和「相互通訊」,這兩個的最終效果實際上是同樣的嗎?
2015年2月 4日 15:48 | # | 引用
天空布藍 說:
看來不少人 MVC纔是最難解 呵呵
2015年2月 5日 10:08 | # | 引用
zy 說:
『惟一的區別是,它採用雙向綁定(data-binding):View的變更,自動反映在 ViewModel,反之亦然』
——>難道不是:Model的變更,自動反映在 ViewModel 嗎?
2015年2月 5日 11:31 | # | 引用
那誰 說:
M=數據對象+數據訪問+業務邏輯,必要時能夠分層
C=路由+視圖邏輯
V=視圖,若是是接口開發這層能夠不要
Fat model, thin controller
是否是不一樣的軟件對MVC的理解不一樣?
2015年2月 7日 22:59 | # | 引用
xuhong 說:
這個是不一樣領域不同的,阮兄這說的應該只是前端領域,否則會形成誤解。對於後端以及ios等其餘領域都是不適用的。
2015年2月10日 19:23 | # | 引用
zhanyaha 說:
http://www.cnblogs.com/winter-cn/p/4285171.html
2015年2月11日 09:33 | # | 引用
lijunwu 說:
只能說都用過,理解仍是不到位
2015年2月12日 02:05 | # | 引用
dark89757 說:
MVVM 中的view是綁定了viewmodel的命令了的,因此我以爲MVVM的view也應該指向viewmodel
2015年2月13日 09:27 | # | 引用
Liuzh 說:
我理解的也是這種狀況。
從如今相似angularjs這種Model才能直接影響view。。
在java中的MVC,應該就是咱們理解的這個V->C->M->C->V
2015年2月13日 14:54 | # | 引用
justNode 說:
我比較認同你的見解。不過博主這篇說的是前端mvc,跟後端仍是有很大區別的。 順便說一句,阮老師對於前端框架的不少觀點都是不穩當的,建議看看寒冬那篇 UI架構設計的演化
2015年2月15日 03:02 | # | 引用
anthony 說:
對MVC的理解誤差很大.
M,V之間是Observer模式,即V直接依賴M,M間接依賴V.M,C之間是C直接依賴M.這兩點是MVC中最普遍承認,同時也是MVC成爲一個解決方案模式的關鍵:視圖和邏輯分離.
理想的MVC模式中V,C之間沒有直接依賴(沒有單向依賴),但現實中作不到.Native應用要通常由view分發事件給controller,controller要決定那些view用戶可見.
Web應用中狀況好一點.用戶能夠直接經過url直接訪問controller,不須要view知道controller,可是controller還負責路由view.前端複雜化後,頁面上與controller交互更頻繁,controller也很難只經過url來實現了.
事實上MVC有三個問題:
1.V和M之間不匹配,用戶界面和流程要考慮易用性,用戶體驗優化同時考慮業務流程的精確和無錯.
2.C和M之間界線不清,什麼樣的邏輯是界面邏輯,什麼樣的邏輯是業務邏輯,很難定義清楚.
3.V的變化不能徹底由Model控制,即observer模式不足以支持複雜的用戶交互.這其實要求VC之間要有依賴.
後來的MVP與MVVM都是爲了優化V,C之間的關係而提出的.
MVP認爲VC之間強綁定不可避免, 但能夠增強P的能力,V變成只顯示,P提供數據給V,把雙向依賴簡化爲P直接依賴於V.
因爲V的數據由P提供,則MV之間的Observer關係轉移到MP之間.
MVP主要解決1,3兩個問題,但代價是加劇了問題2.P更重,並且與Model耦合沒法框架化.但實踐中view很難徹底被動
化,它老是會隨用戶的事件變化,這部分紅爲P的負擔.
而MVVM則是另外一個方面來解決問題.MVVM認爲view應該是事件驅動,模型變化只是一種事件.C應該只處理view與模型不
配合的問題,而問題3能夠經過分離用戶交互與界面構造.C退化爲一個View的模型VM,它與view之間由框架提供事件-
數據的綁定.
MVVM與MVP相比主要完全解決了問題1,從新定義了問題2,在MVVM中VM的功能比較明確,把M翻譯成View須要的數據.
VM有必定視圖的屬性,view與VM有對應關係,也就解決一部分問題3.可是因爲各角色職責已經定義,須要引入第四個
組件來解決這個問題.
咱們能夠打個分,直接依賴計爲1,間接依賴計爲0.5
所有互相依賴是6
理想MVC,MV=1.5,MC=1共2.5
現實MVC根據VC之間的依賴狀況多是0.5到2,實際是3到4.5
MVP,MP=1.5,VP=1,MV=0共2.5與理想狀況一致.
MVVM,MVM=1.5,VM+V=0.5或1,共2到2.5,即不高於理想MVC
2015年2月17日 12:20 | # | 引用
ChenKan 說:
標題改成『前端框架MVC,MVP 和 MVVM 的圖示』彷佛更加穩當
2015年3月 3日 09:52 | # | 引用
Sunny 說:
你好,我的以爲MVC中C應該程序的流轉,非業務處理
2015年3月13日 11:04 | # | 引用
wang 說:
avalon.js也是一個MVVM的javascript框架
2015年3月22日 22:51 | # | 引用
陳計節 說:
感謝分享,我以爲您的補充十分必要。
2015年3月23日 22:55 | # | 引用
陳計節 說:
幾個不一樣的意見。
如 ChenKan 所言,請網友注意,阮兄此文主要講到前端的 MVC 和相關模式的討論。
1. 做者提到 MVC 的兩種流,但舉出 Backbone.js 的例子卻全然不符合這兩種例子中的任何一種。由於 Backbone.js 原本是更強調 View邏輯——是 View邏輯,不是 View。View邏輯即 Presenter。所以 Backbone.js 本質上是一種 MVP 模式。之因此有 Router,由於它原本就是一種 Route:沒有這些 Route,一個 RIA APP 同樣工做的很正常;Route 雖然看起來也有 C 的做用,但它更重要的是導航功能,在它裏面對 render view 的調用原本就是反模式,事實證實在 View 的 initialize 中調用同樣合適,參考此文章中的論述:https://lostechies.com/derickbailey/2011/12/23/backbone-js-is-not-an-mvc-framework/。
2. 我認爲阮兄說的兩種 MVC 流程是錯誤的。(1) Model 沒法將數據「發送」給 View,由於它根本不知道 View 的存在,數據應該是由 Controller 持有,並顯示出 View。 (2) 所以,用戶也不是直接操做 Controller,即便是輸入 URL,也能夠認爲那是由 View 觸發的(就像在 View 上點擊了一個連接)。
所以,MVC 的處理流程是 V -> C -> M -> C -> V。
3. MVP 模式實際上就是 MVC,只不過這裏面的 C 主要負責的再也不是業務邏輯,而是界面邏輯了,好比什麼時候顯示/隱藏某個選項卡,綁定 View 事件等。
4. 咱們如今在討論的 MVC 與經典的 MVC 略有不一樣,經典的 MVC 裏,C 是應用控制器,包括路由的概念;而現代軟件 UI 層的 C 一般僅包含界面相關邏輯的處理。
5. 對於 MVVM 的模式,確實在 B/S 和 C/S 界有不一樣理解,這一點值得提醒。
(對上面那篇略做完善,還請阮兄幫我刪除上面那篇評論,很是感謝。)
2015年3月23日 23:53 | # | 引用
zjien 說:
難道我把MVP理解成了MVC?
2015年4月19日 17:02 | # | 引用
goldli 說:
我想,從樓上(s)的討論中,我獲得了一些啓發。但具體在coding時要怎麼用,要用什麼,是要看具體狀況而定的;並且隨着人類思惟的開闊,未來可能會有更好的模式。因此,不用太糾結。先會用,能用好就能夠。不是嘛?
2015年5月 8日 14:36 | # | 引用
fxdan2002 說:
說的很對。
原本是想了解這幾個的區別的,結果查了半天,越看越暈。其實領悟了模式的精髓,能用好就行,至於叫什麼並不重要
2015年6月12日 16:22 | # | 引用
jet755 說:
Comparison of Architecture presentation patterns MVP(SC),MVP(PV),PM,MVVM and MVC
http://www.codeproject.com/Articles/66585/Comparison-of-Architecture-presentation-patterns-M
2015年7月13日 17:32 | # | 引用
newbie 說:
贊同,MVC(mvc mvp mvvm)就是路演成了你理解的這樣,責權分明。過去整個web開發比較容易發現的混亂想象就是:視圖與邏輯混雜在一塊兒,視圖(應用)邏輯與業務邏輯混雜在一塊兒。
2015年8月31日 23:35 | # | 引用
kenshin 說:
@陳計節:
贊同對MVC模式的修正2(1),在移動Native應用中一樣如此,Model和View須要儘量的分離
2(2)也有相似想法web中URL實際上也是在操做view,只不過這個view是瀏覽器自己(本人3年前從web開發轉到移動前端開發)
對於3.MVP,@ anthony講的很是明白。P至關於業務邏輯+界面邏輯
2015年9月 4日 16:54 | # | 引用
葫蘆娃今晚打老虎 說:
看到書的廣告了,買了本書看看
2015年9月22日 21:26 | # | 引用
蔣鑫 說:
mvc原則上model是不與view層交互的吧,model廣義上講不是單單的數據封裝而是承載了明確的業務邏輯處理,固然可能只是簡單的網絡或數據庫存取。controller負責接受用戶交互指令,後對model進行訪問,以後組裝成view,至關於model與view以前的橋樑因此稱之爲控制器。
之因此讓model層負責更多的業務,主要緣由是遍於重構,代碼複用,在一個view層常常變動的場景下,controller相應的也會變,但由於業務層獨立,能夠保證作到最少的代碼變動。
上面提到的是經典的web、app開發,至於如今的前端web mvc,以ember來講,我對它對controller的定義以爲區別於上面的,更像是某種新的模式或反模式。
2015年9月23日 22:36 | # | 引用
ivy 說:
好文章
2015年11月19日 19:29 | # | 引用
hanfei 說:
MVP裏,View能夠直接訪問model,View不能直接訪問model的是Application Model架構
Application Model: Views hand off events to the presenter as they do to the application model. However the view may update itself directly from the domain model, the presenter doesn't act as a Presentation Model. Furthermore the presenter is welcome to directly access widgets for behaviors that don't fit into the Observer Synchronization.
詳見:http://martinfowler.com/eaaDev/uiArchs.html
2015年11月25日 16:53 | # | 引用
劉宇清 說:
作開發三四年了,前段、後端和IOS客戶端都有過一些開發經驗,並且也常常和團隊裏的其餘成員交流開發心得。綜合來看,你們對MVC的模型、視圖、控制器的概念都是一致的,只是因爲在先後端和客戶端不一樣的開發場景下,有不一樣的側重點而已。
好比前端主要是頁面展現和用戶交互,所以MVC中重點在視圖V,有些場景下承擔業務邏輯和交互的控制器C與視圖V徹底放在了一塊兒,而模型M即與服務端交互的接口及瀏覽器本地的存儲操做則做爲單獨的一部分;後端開發就會有很大不一樣,尤爲是隻提供接口時,MVC中就會更側重模型M,視圖V概念則弱化爲了對外開放的接口具體到實現上甚至就是一系列的接口列表,而控制器C則承擔接口的實現及部分服務端操做如定時任務等功能,成爲較厚重的一層,模型M承擔數據庫操做和從其餘服務獲取數據的功能則做爲第三層;客戶端的MVC則通常都較爲均衡,可是界面展現與業務邏輯不少時候仍是會強綁定,形成V與C結合在一塊兒,例如純代碼開發IOS時,每一個頁面的展現及交互邏輯分層很明顯,可是就整個項目來講,視圖V並無造成單獨的一層,是成爲了控制器C層的一部分。
於是,MVC也好,MVP也好,MVVM也好,重要的是針對應用場景和需求對M、V、C三層進行劃分,三層間的交互也是如此。只要肯定了架構後遵循必定的原則,在開發過程當中儘可能不破壞原有規則,直到現有的架構規則不能知足需求,再從新制定。這樣應該就能在知足應用場景需求的同時,使得項目有明確清晰的層次。在比較框架的定義和優劣時,也要有必定的場景說明纔有實際意義。
回到阮老師的總結,我的感受他是從廣義上對這些框架進行講解的,咱們在理解時,應該根據不一樣項目的實際狀況進行參照。你們在評論的時候最好說明是在什麼樣的場景下框架的使用,這樣也方便不一樣開發背景的同窗學習。
2015年12月 5日 14:47 | # | 引用
Sinksfish 說:
誰跟你說的MVC是單向的?
Model能直接操做View?Model是禁止操做View!
Controller就不能操做View?Controller就是Model那取到數據再去操做View
2015年12月25日 11:00 | # | 引用
windsSunShine 說:
對啊我也是這樣認爲的
2015年12月30日 19:18 | # | 引用
cshenger 說:
這樣理解的話,我以爲區分MVC與其餘的區別是否是View和Model能不能直接通訊,至因而單向仍是雙向我卻是以爲是否是跟具體的業務有關?我的拙見,固然阮老師寫的至關清楚明白,謝謝
2016年1月12日 17:47 | # | 引用
daoren 說:
我這兩天也特意去查mvc相關知識,獲得的點是:
1. 經典MVC設計是給非web系統的,
2. MVC web框架其實不是真正的MVC設計模式,而是JSP Model2設計模式。
參考:
http://stackoverflow.com/questions/1931335/what-is-mvc-in-ruby-on-rails
http://www.sitepoint.com/getting-started-with-mvc/
https://www.wikiwand.com/en/JSP_model_2_architecture
2016年2月24日 11:12 | # | 引用
落風月 說:
MVC的那個圖錯了吧…m與v並不會直接交互
2016年3月10日 08:43 | # | 引用
kylelua 說:
一派胡言。做者你懂mvc 嗎????model 和 view永遠不能夠有任何直接聯繫。此乃mvc的最大忌諱。竟然你一開頭開始就扯淡。
2016年3月24日 10:56 | # | 引用
公孫二狗 說:
1. Web 的 MVC,Model 不知道 View 的存在
2. 而 Swing 等的 MVC,View 裏放了 Model(例如 JTable 裏有 TableModel),Model 數據變化時觸發事件,View 會收到這個事件觸發更新操做
2016年4月12日 08:28 | # | 引用
Seanix 說:
很是棒的講解, 對於新人頗有幫助~! 謝謝博主~~~!
2016年5月 6日 17:06 | # | 引用
bounty 說:
mvc 模式講錯了,阮老師,view發送指令給controller,controlle接受指令通知model層操做數據,接着返回controller層,controller再渲染view。
2016年5月11日 10:58 | # | 引用
王大大 說:
MVC 的 C 怎麼回事業務邏輯呢?
2016年5月26日 16:09 | # | 引用
咚門 說:
。。。我一直在嘗試跟個人後端經驗對應,沒想過這個。。。
2016年5月31日 11:09 | # | 引用
panda 說:
這個mvc和後端的mvc感受不同啊,本文說處理邏輯都在v層,不是應該在m層嗎?mvp和mvvm都基本沒說m層做用,一直在說v和c層之間關係,不是很明白。
2016年6月10日 12:29 | # | 引用
王凌永 說:
清晰易懂 謝謝!
2016年6月13日 10:37 | # | 引用
is 說:
圖掛了
2016年6月13日 22:15 | # | 引用
xgqfrms 說:
被誤解的MVC和被神化的MVVM!
2016年7月 1日 23:24 | # | 引用
zhongHao 說:
感受好多人混淆了傳統 MVC 跟 web MVC 的區別了,MVC 模式建立出來是爲了 n-tier systems,固然一開始不是用在 web 應用上的,就如老師是說的,我認爲並無錯誤,web MVC 是後來的人把這種設計模式用於 web 應用中,固然是有區別的,固然你問我區別是什麼?仍是問谷歌和度娘吧,本人仍是個菜鳥,歡迎指點。:)
2016年7月19日 01:07 | # | 引用
八爺 說:
不必定,好比在android上,activity既能夠當View,也能夠當Control,那麼他就很厚了,在mvp上,把他定義爲view,其實我的以爲,只要清晰易懂,用什麼框架無所謂!
2016年8月24日 14:12 | # | 引用
AppDays 說:
我以爲 MVC 和 MVVM 的本質區別在於綁定,分層結構上面我以爲大同小異
2016年8月29日 12:05 | # | 引用
心止如水 說:
Android裏的MVP感受和當年寫Java EE時候的MVC差很少,不一樣的是當時的MVC接受請求的是C(Controller),C負責加載數據與渲染視圖,MVP中V(View)接收請求通知Presenter加載數據再把數據渲染到V,不知道這樣理解對不。
2016年10月16日 23:53 | # | 引用
慕容玄 說:
對於分層,很是不理解爲何要搞這麼多名堂,有誰能告訴我VM層比C多了什麼?多的那些在之前沒有MVVM的時候,是否是不少程序員也會把這些內容寫到C?整體的思想難道不仍是數據、試圖、控制麼?樓主的作法更讓我費解,我從05年開始學MVC的時候開始,就沒有哪一個老師或者哪份資料裏規定過說MVC的通訊必須走單項或者雙向,考通訊方式來劃分,是否不三不四?難道咱們說的接口不是分層而是通訊麼?
2016年11月17日 17:32 | # | 引用
必富客 說:
MVC錯了,改改。
2016年11月25日 08:29 | # | 引用
AAA 說:
好多人說文章的MVC錯了.說M不能和V通訊.是否是大家接觸的MVC不同?
文章中的MVC是對的.V -> C -> M -> V , MV之間實際上是一個Observer模式,M 自己做爲一個事件派發器,V 註冊監聽M的事件,當M 被C 改變時,拋出DataChanged事件+數據,V收到事件後去更新控件上的數據.
可能遊戲編程和web編程不同吧.
2017年1月10日 21:15 | # | 引用
gcc 說:
一本正經的胡說八道,mvc說得根本不對。
2017年1月14日 13:55 | # | 引用