你對MVC、MVP、MVVM 三種組合模式分別有什麼樣的理解?
MVC(Model-View-Controller)
MVP(Model-View-Presenter)MVVM(Model-View-ViewModel)請大家談一談各自的理解吧,對比之下更能明確特徵和適用的範圍,菜鳥們暢所欲言,老鳥大牛們請多多指點!
我是大自然的搬運工。
這是我在博客園正好寫的一篇Blog,希望對你有用:從Script到Code Blocks、Code Behind到MVC、MVP、MVVM
=====================(Hi,我是分割線)=====================
剛過去的周五(3-14)例行地主持了技術會議,主題正好是《UI層的設計模式——從Script、Code Behind到MVC、MVP、MVVM》,是前一天晚上才定的,中午花了半小時準備了下就開講了。
今天看到了大家在為MVVM knockout.js友(ji)好(lie)地交流,所以就整理下然後更擴展地分享。
主要目的也不是為了爭論,畢竟只是正巧主題相近,原本的打算也就是一次技術分享並且記錄下來。
那麼我們就按照大致的歷史進程將這些概念進行劃分:
- Script
- Code Blocks、Code Behind
- MVC、MVP、MVVM
我們知道的是現實的歷史發生順序並不如上,因為思想都是相似的,比如MVC很早很早就出現了,解釋型語言至今基本上也有很多分支而且在互聯網時代大行其道。
但我要說的是:不要在意這些細節!
當然了,這是玩笑,我的意思是,這些內容我懶得應該在另外獨立的主題探討,篇幅也有限。
- Script
這裡腳本的意思不是指當時是用腳本開發,而是像寫腳本一樣開發。它們都有一個特點:功能單一、管理單一、入口單一。
我們最早的程序是彙編,當時的碼農的工作是兼職,工作內容是編寫一套壽命不長的機器控制指令,有些甚至是命令,比如至今依然保留的Command(亮點自尋):
到後來計算機被用於科學計算等,需求推動了需要更高的開發效率,所以我們有了高級語言。
那個時候碼農其實多是數學家,程序的作用很簡單,就是執行一些數學計算,類似今天ICPC的一些演算法問題,比如Hello World:
main()
{
printf("hello,world
");
}
這時候,程序還可以被歸結為輸入到輸出的過程,我們還能去講講馮諾依曼模型。
在這個時代,開發是指編寫機器指令,甚至都不配用「開發」這個詞來描述這項工作。
軟體、UI和Markup Language在那個時代講UI等於放屁,根本不存在這種概念。但全賴我們有神器——摩爾定律。
但我個人認為摩爾定律是不足以讓一個敲命令行的時代在幾十年間轉變成這種各類框架技術架構實踐模式的時代,真正推動計算機形成自有的工程學體系的是還有兩樣東西就是:
- 人的能力並沒有變強,至少沒有在同級數下變強。
- 人類一定會物盡其用
因為人的能力並沒有「跟上」機器,所以才會出現各種模式、方法、工具等等來補足人的不足,以最大地透支機器性能。就像我前幾天在快閃記憶體無聊時突然想到的一句: 架構是對客觀不足的妥協,規範是對主觀不足的妥協。
當我們需要機器做的事情多了起來,我們就沒辦法在一個晶元上解決所有事情,所以才會有馮諾依曼模型、計算機架構,沒辦法用一台機器解決,所以才要互聯網、分散式、雲計算。
同樣,隨著計算機的發展,要做的事情多了,就出現了軟體的概念。當「開發」正式化,我們需求的軟體就變得:功能繁雜、管理統一、多入口。
真正變化的不是客觀本質,而是需求。就像這裡說的「軟體入口」在客觀上我們還是只有一個,原理上始終都只有一個啟動程序、一個啟動代碼片段。但「軟體的入口」,已經從指代Main函數變成了指代起始UI,用戶已經從指代專業人士變成了指代一般消費者,先有軟體的需求,才有軟體的定義,而需求是在變化的。
一個軟體需要比當時多幾個數量級的代碼:
- 客觀上我們沒辦法做一個能顯示所有代碼的顯示器
- 主觀上我們沒辦法在超快速滾動中看清所有代碼
所以我們需要添加索引、用多個文件組織代碼。
機器的發展和軟體的需求擴大和細化,我們開始出現了用戶界面(User Interface)的概念和最適合用於界面的語言——標記語言(Markup Language)。當然,ML不是為UI而生的,它只是十分適合UI,所以才和UI墜入愛河。
因為有了更高UI的需求,所以代碼才正式被分化為描述做什麼(業務邏輯)和有什麼(UI)的兩部分,因為我們開發時沒辦法在兩種思維方式下同時工作,開發時的人腦是單線程的。我們所看到的同時進行UI和邏輯開發只不過是我們學會了在兩種模式下快速切換,看起來像同時進行,而不是真正的同時進行。同樣的情況也發生在不同的代碼片段的開發中。
分化的情況除了UI,還發生在方方面面,比如數據操作、UI的對象和樣式分離,我們還是繼續從UI講下去吧。
- Code Block和Code Behind(其實還有Code Inside,比如onclick="javascript:alert("哎呀我*")")
UI和邏輯分開了兩種語言來寫,但是它們也要放在同一個項目中,因為它們原本就是要一起工作的。即使是分開,也需要相連,因為這是它們本來要解決的問題。
這時候我們出現的(通常的)解決方案就是Code Block和Code Behind。雖然從時間上似乎Code Block比Code Behind要早,有種感覺就是越新越好,但實質上它們正交替地發展著,因為誰也沒辦法解決UI和邏輯代碼分化後的一個哲學問題——UI和邏輯是一起的,但是它們卻不是一起的。
Code Block能很好地處理UI和邏輯間在一起的關係,你在同一個地方可以同時維護UI和邏輯:
1 @model GM.OA.Finance2.Web.Models.FinancialBase.CurrencyModel
2 @{
3 ViewBag.Title = "EditCurrencyDrawer";
4 Layout = "~/Views/Shared/_DrawerLayout.cshtml";
5 }
6
7 @section styles {
8 &
9 &
10 }
&添加新幣別&
&
Code Behind能很好地處理UI和邏輯各自分開的關係,你可以讓UI和邏輯各自做好各自的事情:
&
&
1 protected void RemoveSelectedCurrency_Button_Click(object sender, EventArgs e)
2 {
3 var currencyId = Currencies_ListBox.SelectedItem.Value;
4 currencyManager.Remove(currencyId);
5 }
6
7 protected void RemoveAllCurrencies_Button_Click(object sender, EventArgs e)
8 {
9 currencyManager.RemoveAll();
10 }
因為存在兩種實現方式,所以就存在了對比,因為存在了對比,所以就存在了爭論。就像是Java和.NET、PHP和.NET、WebForm和MVC、Mac OS和Windows、iOS和Android、騰訊和所有其他互聯網公司,等等。
問題不在哪個更好,而是我們要解決什麼問題。當然,這聽(ben)著(lai)像(jiu)是客氣話了。
真正在UI和邏輯分化後帶來的實質問題是:
- 是按邏輯和UI劃分地管理,還是按單界面的事務進行劃分地管理
至少UI和邏輯剛分化的時代,在軟體上,我們還認為同一項事務是基於同一個UI的一系列操作完成的。
在摩爾定律還持續發揮作用的時候,計算機領域依舊高速發展,所以通常我們還在為一樣事物爭論、思考、辯證的時候,它已經發生了質變了,不變的只是我們要解決的問題。
- 事務,以及界面、數據、事件、業務
在之前說到過了,當需求變得龐大,解決方案也會變得龐大;當解決方案變得龐大,就會出現細分;當出現細分,就會出現按哪種方式管理的問題。
軟體從處理一件事務發展到了要處理許多事務,各事務間有包含、順序、主次等等的關係,變得越來越複雜。因為數據與邏輯龐大了,所以數據與邏輯就分離了,然後事件和業務分離了。
它們的關係已經在我們還理得清之前持續發展而變得更加難理得清,但在一個時間點上,它們UI的領域大致分化成這些原子:
- 界面
- 數據
- 事件
- 業務
你要細化的話會有更多繁雜的細節,但相信這麼寫的話爭議性比較小。
當一個問題出現一次的時候它是一個問題,當一個問題出現了無數次的時候它會成為歷史,當一個問題將會出現無數次的時候,它將需要一個明確的定義和解決方案。
其中,數據的更新和界面的更新這一特殊事件的問題被放大了無數倍,因為它出現了無數次。
- Model-View-Controller
在ASP還在奮鬥的時候WebForm突然到來,正如WebForm還在奮鬥的時候MVC突然到來。當然,我這裡講的MVC還是最原始的MVC,因為MVC在我們還在爭論的時候已經發展了許多不同分支了。
有一點相信大家同意的就是,我們今天討論爭論的MVC、MVP、MVVM、Code Behind等等都源自於職能分化和規劃的思想與目的,MVC不是它們的開始,但是一個很好的開始。
相信MVC的模型大家很熟悉,也很容易找到,我們這裡用一下某百科的圖:
我們可以看到的是,界面被分到了View,數據分到了載體Model上由Model「攜帶」,業務集中在Controller中,而推動業務的事件由用戶與View交互,通過View向Controller發動。
當然,實現由很多種,每種細節上都有不同,所以我才只講也只能講大致的MVC。MVC的其中一個缺點便是沒有明確的定義,所以不同的實現(比如Struts和http://ASP.NET MVC)細節上都是不一樣的。
我們需要知道的是,MVC並不是像上面所說的一些事情那樣是一種「必然的」結果,它是一系列必然結果問題中的一種解決方案,而且是不完美的解決方案。我們順著推理去到一個地方很容易犯的一個錯誤就是認為路只有這一條而忽視其他可能性(估計這也是導致很多爭鬥的原因)。另外,我們在討論一件事物不完美的時候是有一個情境的,所以請不要像「我說它色彩單一,然後你把它塗成彩色後證明我是錯的」。
MVC的一般流程是這樣的:View(界面)觸發事件--》Controller(業務)處理了業務,然後觸發了數據更新--》不知道誰更新了Model的數據--》Model(帶著數據)回到了View--》View更新數據
這裡也不多再陳述MVC的原理、實踐等等,因為這就太長篇大論了。
- Model-View-Presenter和一些衍生
像我們之前推理的,分化是一種需求的必然結果,但卻沒有個一個確定的結果,比如Code Behind和Code Block的問題等等。
MVC順著需求把UI相關的工作分化成了三份,這點經過實踐證明無可厚非。但是它們的三角關係卻被一些人認為帶來了一些問題,或者應該說他們有「更好的」解決方案。
在只有Code Behind和Code Block的那個時候維護是很直接的,不是在同一段代碼內解決就是在同一個關聯的事件上解決。三角關係的問題就是維護問題。在MVC,當你有變化的時候你需要同時維護三個對象和三個交互,這顯然讓事情複雜化了。
我們之前說到,隨著摩爾定律,軟體的需求不斷地變化和變得龐大。隨著需求變得龐大的時候,需求變化也變得頻繁,這是一個出現了無數次以後也將會出現無數的無數次的一個問題,所以它需要一個解決方案,哪怕它不一定能被解決。
為了解決需求變化,從《人月神話》到敏捷到DDD,它不是我們已經解決了的問題,而是我們正在解決的問題。放在UI的模式和MVC上來講,就是優化或者替代MVC模式,其中之一就是Model-View-Presenter(MVP)模式。
我們先看看兩個MVP模式的圖:
(圖一)
(圖二)
兩幅圖是不同的,但是對MVC的改進的思想卻是一樣的:切斷的View和Model的聯繫,讓View只和Presenter(原Controller)交互,減少在需求變化中需要維護的對象的數量。
這種方式很符合我們的期待,因為我們傾向於:
- 用更低的成本解決問題
- 用更容易理解的方式解決問題
許多時候並不是一種模式不好,而是因為人沒辦法執行,比如不容易理解,我們就會選擇容易理解的方式。計算機依賴摩爾定律用數量的增長來解決問題,而人是用方式的改變來解決問題的。同樣因為客觀原因我們不善於維護多個對象和多個對象之間的關係,所以我們改變了,或者說簡化了這種方式。
MVP定義了Presenter和View之間的介面,讓一些可以根據已有的介面協議去各自分別獨立開發,以此去解決界面需求變化頻繁的問題。上面兩圖都有介面,不過介面的實現和使用細節不一樣,不過思想上是一致的。
在這裡要提到的是,事實上,需求變化最頻繁的並不一定是最接近用戶的界面,但基本可以確定的是,最接近用戶的界面是因為需求變化而需要最頻繁更改的。當然,如果View如果是API而不是UI,那就另說了。
還有一些用來「解決」MVC這項缺點的比如有:http://ASP.NET MVC的ViewBag,Cocoa的delegate。它們都為了簡化數據更新的問題而存在,包括MVVM。
- Model-View-ViewModel
先直接看看Model-View-ViewModel(MVVM)的圖:
從圖上看是比MVP簡單了,更不用說MVC了。個人不認為MVVM是從MVP進化而來,我只覺得這是在MVP之後出現的一種「更好的」UI模式解決方案,但是用MVP來與之對比比較容易說明問題。
ViewModel大致上就是MVP的Presenter和MVC的Controller了,而View和ViewModel間沒有了MVP的界面介面,而是直接交互,用數據「綁定」的形式讓數據更新的事件不需要開發人員手動去編寫特殊用例,而是自動地雙向同步。數據綁定你可以認為是Observer模式或者是Publish/Subscribe模式,原理都是為了用一種統一的集中的方式實現頻繁需要被實現的數據更新問題。
比起MVP,MVVM不僅簡化了業務與界面的依賴關係,還優化了數據頻繁更新的解決方案,甚至可以說提供了一種有效的解決模式。
至此,我們能理解為什麼許多人認為MVVM是最好的一種模式,沒有之一。但事實上,MVVM也是依賴於我們至今所講的「特有的情境」。
當然,最優雅的也是第一個能作代表的實踐就是Windows Presentation Foundation(WPF)了。
- Web
之上,我們在模式演變的推論基本上都還是基於桌面軟體的,但是過去十年卻是互聯網的時代。實際上大部分讓大家爭議的並不是在桌面領域最合適的是那個,而是在Web領域的模式問題,也就是在B/S場景下的問題。
當軟體離開單機,去到網路的時候,因為場景變了,所以原有的解決方案也變了,不過需求依然是不變的。我們依然要解決的問題是用戶交互與數據更新的問題,還有維護等等的問題。
當場景變到Web的時候,我們發現MVVM用來做服務端是極其不適用的,至少現在是不適用的。而MVP你提都不用提。為什麼呢?因為:
- 網路資源成本過高
- 開發成本過高
問大家一個問題,當一個網頁的數據更新後,你希望更新用戶看到的數據,你會怎麼做?
一般情況下,你會:
window.location.reload();
就算你不這麼做,用戶也會:
F5
就像之前說的,我們會選擇更直接的方式解決問題。直接刷新頁面的原因是因為這樣更直接,更容易解決數據更新的問題。
很多時候你不會願意為了一個數據更新寫一個AJAX,更別說這個AJAX要帶來Loading、事件順序處理、網路問題、異常處理等等,這就是開發成本過高。
另一個網路成本過高就更容易解釋了,雖然寬頻是基本包月的,但也不帶這麼用的,何況還有移動用戶。更主要的原因是,在本地軟體,更新數據是一個引用問題,而在網路應用上,這是一個傳輸問題。傳輸成本遠高於引用成本,引用之上頂多是在本地內存中再進行一次內存拷貝。
這個時候,我們會更傾向於用MVC模式,因為在Web層面,我們更傾向於一次性更新數據。
- Web的MVVM
所有問題都不是問題,就算有問題也要解決問題。
為什麼這個標題下突然冒出這麼一句話?我想說的是,需求依舊是不變的,是推動進步的原動力。
還有我之前說過,當我們討論或者爭論一個問題的時候,問題的對象已經發生改變了,而且這次是在我們討論這個問題之前已經發生改變了。
網路資源成本不斷下降,相信已經不需要多提及。摩爾定律和相近的一些原理正在發揮著它應用的作用,網路帶寬越來越高、相應速度越來越快。
如果傳輸因為相對成本下降而導致數據傳輸的成本低於開發人員拒絕客戶的成本,那麼它就會被實現而不是被拒絕。
另外還有一點就是因為技術的進步,技術的資源不斷被更大規模地壓榨,需求也不斷地增長,那麼需求始終會增長超過相對不變的開發成本的。比如jQuery的出現解決了很多問題,我們現在更多地去使用AJAX,哪怕很大一部分依然是為了解決網路資源不足的問題;我們會用更多的樣式代碼而用了相對更少的圖片;我們不再那麼依賴Flash一類的矢量圖解決方案而直接錄製視頻。
至少上一節我們說到的兩個導致大家選用MVC的問題都正在被解決,所以我們有理由相信未來Web不僅僅需要MVC,可能會需要MVVM或其他解決方案。至少我們能理解容易理解為什麼前端會出現一些MVVM的框架,比如先驅knockout.js和AngularJs。這些框架本身的好壞就不作討論了,因為我們討論的是模式。
在Web上,MVVM的對比對象就不是MVC,而是Code Block。
數據即時更新的需求在擴大,但未必有達到一定要用MVVM這一等級的高大上的模式,實際上如果你要更新一個數據,你還是會採取:
$(".notice").html("發送成功!");
因為......我們依然會採取更直接的方式解決問題......
實際上,現在Web MVVM主要並不是用在了Web或者Wap上,而是移動App上。按照前面的說法,只可能是:
- HTML+JS比原生在一些場景上更適合Native
- 在移動App上比Web上更適合使用MVVM
哪怕是Native開發,實際上iOS的開發上也是用類似的數據綁定的方式的。這裡也不深究了,畢竟我也不算懂iOS。
要說的是,在Web MVVM或者Web的模式上,也就是Web的富應用上,現在還不過是個初期由膨脹的需求推動的階段。重要的不是技術會怎麼走,而是需求和客觀條件會怎麼走。
可能Webform會因為高速開發而煥發第二春,它的AJAX的模式也十分滿足於簡單開發,但似乎大家需要的不是GUI式的網頁。
- 結尾語
我們不一定需要MVVM,但我們一定需要更強大的方式去解決不斷膨脹的Web需求。
我們可以預見的是:
- 會有更強大的瀏覽器
- 會有更強大的JavaScript或者框架
- 會有更加適合的模式
除去客氣話的部分,我還是想說,在不同的需求下其實有最適合的解決方案,通常讓我們糾結的不是因為哪個解決方案更好,而是我們看到的條件不夠多。
編譯語言當然比解釋語言效率高,但考慮到開發和維護成本,JavaScript等始終會大行其道,比如Node.JS、Python;.NET和微軟當然很強大,移植.NET到其他平台也很容易,但微軟是家有自己商業模式和要賺錢的公司;當然有些實踐和技術更好,但其他開發人員會避開甚至否定自己不擅長的東西,大家都喜歡確定的東西;有些技術更強大,但是只是基於特殊的客觀條件和需求,如果你想做大,要麼創造客觀條件,要麼把它結合需求......
只是一點淺見啊 摺疊也活該。。。
M-V- X 本質都是一樣的 重點還是在於M-V 的橋樑
要靠 X來牽線。
X的模式之間不同 主要是 M與V 的數據傳遞的流程不同。
數據傳遞的流程不同來源於運行環境技術棧能夠做到的事情不同。
所以無論是複雜化 簡單化 還是修改流程,基本都是因為技術棧變化了 對應做的調整。
在相同技術棧下 能夠實現的各種 X都可以是大同小異的。
在不同技術棧下 相同的X可能實現都大相徑庭,僅有非常抽象的流程類似。
俺是做Android開發的。重點從Android角度詮釋。以下全是胡說八道,僅供參考。首先,我們先大致了解Android開發中常見的模式,以便我們更深入了解MVVM 模式。
- MVC
View:對應於xml布局文件
Model:實體模型Controllor:對應於Activity業務邏輯,數據處理和UI處理從上面看起來各個組件的職責視乎還挺耦合MVC的,但是打開Android的一個Activity文件,一看一言難盡, Android中經常會出現數千行的Activity代碼,究其原因,Android中純粹作為View的各個XML視圖功能太弱,Activity基本上都是View和Controller的合體,既要負責視圖的顯示又要加入控制邏輯,承擔的功能過多,代碼量大也就不足為奇。所有更貼切的目前常規的開發說應該是View-Model 模式,大部分都是通過Activity的協調,連接,和處理邏輯的。
- MVP
View: 對應於Activity和xml,負責View的繪製以及與用戶交互
Model: 依然是實體模型Presenter: 負責完成View於Model間的交互和業務邏輯在Android開發中MVP的設計思想用得比較多,利用MVP的設計模型可以把部分的邏輯的代碼從Fragment和Activity業務的邏輯移出來,在Presenter中持有View(Activity或者Fragment)的引用,然後在Presenter調用View暴露的介面對視圖進行操作,這樣有利於把視圖操作和業務邏輯分開來。MVP能夠讓Activity成為真正的View而不是View和Control的合體,Activity只做UI相關的事。但是這個模式還是存在一些不好的地方,比較如說:
- Activity需要實現各種跟UI相關的介面,同時要在Activity中編寫大量的事件,然後在事件處理中調用presenter的業務處理方法,View和Presenter只是互相持有引用並互相做回調,代碼不美觀。
- 這種模式中,程序的主角是UI,通過UI事件的觸發對數據進行處理,更新UI就有考慮線程的問題。而且UI改變後牽扯的邏輯耦合度太高,一旦控制項更改(比較TextView 替換 EditText等)牽扯的更新UI的介面就必須得換。
- 複雜的業務同時會導致presenter層太大,代碼臃腫的問題。
- MVVM
View: 對應於Activity和xml,負責View的繪製以及與用戶交互
Model: 實體模型ViewModel: 負責完成View於Model間的交互,負責業務邏輯MVVM的目標和思想MVP類似,利用數據綁定(Data Binding)、依賴屬性(Dependency Property)、命令(Command)、路由事件(Routed Event)等新特性,打造了一個更加靈活高效的架構。
- 數據驅動在MVVM中,以前開發模式中必須先處理業務數據,然後根據的數據變化,去獲取UI的引用然後更新UI,通過也是通過UI來獲取用戶輸入,而在MVVM中,數據和業務邏輯處於一個獨立的View Model中,ViewModel只要關注數據和業務邏輯,不需要和UI或者控制項打交道。由數據自動去驅動UI去自動更新UI,UI的改變又同時自動反饋到數據,數據成為主導因素,這樣使得在業務邏輯處理只要關心數據,方便而且簡單很多。
- 低耦合度MVVM模式中,數據是獨立於UI的,ViewModel只負責處理和提供數據,UI想怎麼處理數據都由UI自己決定,ViewModel 不涉及任何和UI相關的事也不持有UI控制項的引用,即使控制項改變(TextView 換成 EditText)ViewModel 幾乎不需要更改任何代碼,專註自己的數據處理就可以了,如果是MVP遇到UI更改,就可能需要改變獲取UI的方式,改變更新UI的介面,改變從UI上獲取輸入的代碼,可能還需要更改訪問UI對象的屬性代碼等等。
- 更新 UI在MVVM中,我們可以在工作線程中直接修改View Model的數據(只要數據是線程安全的),剩下的數據綁定框架幫你搞定,很多事情都不需要你去關心。
- 團隊協作MVVM的分工是非常明顯的,由於View和View Model之間是鬆散耦合的。一個是處理業務和數據,一個是專門的UI處理。完全有兩個人分工來做,一個做UI(xml 和 Activity)一個寫ViewModel,效率更高。
- 可復用性一個View Model復用到多個View中,同樣的一份數據,用不同的UI去做展示,對於版本迭代頻繁的UI改動,只要更換View層就行,對於如果想在UI上的做AbTest 更是方便的多。
- 單元測試View Model裡面是數據和業務邏輯,View中關注的是UI,這樣的做測試是很方便的,完全沒有彼此的依賴,不管是UI的單元測試還是業務邏輯的單元測試,都是低耦合的。
通過上面對MVVM的簡述和其他兩種模式的對比,我們發現MVVM對比MVC和MVP來說還是存在比較大的優勢,雖然目前Android開發中可能真正在使用MVVM的很少.
通過一系列的學習,消化和參考。目前,MVC,MVP都已經應用到項目開發中了。關於MVVM目前是只聞其聲,不見其下樓。MVVM算是舶來品,從Web前端的Argular而來。Argular有個databind的屬性領我們羨慕不已,瞬間感覺高大上啊!其實,還有WPF,這個落寞巨人微軟的背影。這個有個點感覺很牛逼就是,界面開發和業務開發完全分開實現。界面開發除了數據是假的,業務操作綁定,顯示全是真的,業務流程的定義和界面設計進行了解耦,二者通過介面文檔,默認命名規則進行約定實現。最後界面顯示和業務處理拼合起來就好了。我覺得除了databind (現在有robobinding可以參考),還需要 有事件訂閱與發布 的模塊(推薦使用使用facebook的flux),相關技術用到RxJava,RxAndroid的模塊。而後再加上代碼自動生成,通過web伺服器的資料庫,直接生成業務處理代碼與介面,Android端也自動生成業務處理類。著多牛逼啊,然後Android開發失業。web開發失業。資料庫設計和界面開發笑到了最後。這都是我們對於mvvm的自嗨和幻想+YY,Google大兄弟目前還沒有推薦的技術實現。感覺Google處境很尷尬,現在Facebook 推出的 React Native 如日中天,大有替代Java 原生編程的趨勢。如果真取代了,Android Application 將是 Node.js JavaScript的樂園。我們原生應用的開發工程師可要下崗了。目前已經在不斷蠶食Android原生開發的份額,通過Cordova這個內奸,Html5家族由原來的jQuery Mobile 到 Augular.js 和ionic,再到 React 和 React Native,來勢洶洶。JS是如日中天,蓬勃發展。再回來討論MVVM竟然是前端帶來的技術。遇見的未來競爭會更激烈。廣大Android原生開發的從業者受的的衝擊會更大。ps:要不我們轉粉JavaScript教,Node.js教,修鍊React Native 大法?談談我對mvc的一點看法:
web中的mvc不牽強,mvc解決的最重要問題不是所說的「模型與視圖的信息同步」。
mvc解決的最重要問題是m和v的分離,以及v和c的分離。 m是領域相關的業務邏輯,不應當因v的改變而改變。所以v-&>m的單向依賴是很重要。vc的分離重要性相對mv分離較弱,傳統gui比如mfc document/view framework的vc就沒有分離,因為vc一般是一一對應的,強行分離也會有其它開銷。
傳統gui多視圖的情況會使用觀察者模式,m修改會主動notify view。但web情況有所不同,一次請求只有一個v,而且v的展現在遠程客戶端,v的產生在server端,m主動notify view,讓view刷新就沒有必要。直接在v創建時讀取m即可,有的web mvc實現v-&>m的依賴也有所削弱,v由c從m讀取填充。
總之,不能以是否使用了觀察者模式來區分是否是mvc。在看薦前端分類中有提到框架模式:框架模式不是一門寫代碼的學問,而是一門管理與組織代碼的學問。其本質是一種軟體開發的模型。與設計模式不同,設計模式是在解決一類問題時總結抽象出的公共方法(工廠模式,適配器模式,單例模式,觀察者模式 。。。 。。。),他們與某種具體的技術棧無關。一種框架模式往往使用了多種設計模式,切不要把他們的關係搞混。不管是 mvc 還是 mvp 或 mvvm ,他們都是 數據驅動 的。核心上基於 m 推送消息,v或p來訂閱 這個模型。使用者需要維護的不再是 UI 樹,而是抽象的數據。(通過數據,可以隨時構建出新的 UI 樹), 當 UI 的狀態一旦多起來,這種框架模式的優勢便體現出來了。 因為維護數據可比維護 UI 狀態爽多了。
分享一篇之前看過的文章:Understanding MVC And MVP (For JavaScript And Backbone Developers)。
Thaks study of @Indream Luo , slide 4 ppt.
MVP、MVVM模式為MVC模式的更進一步。MVVM是微軟社區的叫法,他源由Martin Fowler的Presentation Model模式 - Model View ViewModel。對於他們的理解還是看Martin Fowler的原始文章比較好 - Presentation Model。我們幾年前開始為Android開發了一個開源的Presentation Model實現框架RoboBinding - http://robobinding.org。目標為減少android應用開發工作量(減少50%UI代碼量);促進清晰的項目結構;使項目代碼更易於測試(使大部分代碼可用JUnit直接進行測試)。有興趣的朋友,可以了解一下。這裡有介紹的中文視頻 - Android MVP MVVM Presentation Model模式與基於RoboBinding應用 (視頻質量太差) 或 https://www.youtube.com/watch?v=2sSBVaX77xA (視頻質量好)
對MVC和MVVM都做過大型的項目。但如果要回答兩者的區別還一時回答不上來。因為沒特地的想過。如果你單獨的接觸它們,不對比他們的話。這個本來就不是問題的問題。這樣會更好,讓你有時間去思考一些更有價值的東西。我覺得MVC是受限制於web體系的局限所產生出來的框架。怎麼說呢,如果將來web體系進化了,前端能夠非常方便的知道後台的狀態的時候,MVC又會自然而然的演化成MVVM了。這是我的看法,希望對你有幫助。
各大軟體和系統,包括現在的手機,都趨向於mvp,web更傾向mvc但是也有趨向於mvp的。感覺核心就是從mv+一個代理方式,只要這個方式方便測試,降低耦合就會不斷改進
模式來源於需求和開發水平。我接觸過mvc模式和mvvm模式,mvvm模式最大的特點是讓設計和開發分離,我們項目 組的人員可以做到設計人員用blend畫好框架,直接上代碼。如果你做不到這點,一切還是開發人員包辦,其實差別並不多。
mvc的controller要接受請求,更新UI,show the code
void controller(){
Edit username = getEditById("username");
View tips = getViewById("tips");
edit.setKeyListener(new Listener(Event event){
//驗證
String username = event.getSource();
if (username.length()&>10){
tips.setText("...");
//更新UI
tips.update();
}else{
tips.setText("...");
//更新UI
tips.update();
}
//後面還有一大堆業務邏輯
});
}
mvvm 的 ViewModel
ModelProperty username;
ModelProperty tips;
void viewmodel(){
username.watch(new Listener(){
if (username.length()&>10){
tips.set("...");
}else{
tips.set("...");
}
//後面還有一大堆業務邏輯
}
);
}
mvvm 的框架幫你做了很多事,比如獲取視圖,更新UI等,你的ViewModel只要關心數據就行,數據變化,UI自動更新,這樣最大的好處就是ViewModel與View解耦了,當有一天是視圖的控制項改變了,你看下第一個例子,要改得多痛苦,而且第二個例子不用改一行代碼。
Martin 大叔早有詳細解釋了。
GUI Architectures
我是 Google Plus 的搬運工:
From Igor Minar:原文:https://plus.google.com/+IgorMinar/posts/DRUAkZmXjNVMVC 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"snow closer to MVVM – the $scope object 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.
Nodejitsu 的這篇寫的不錯,雖然他的主題是適用於前後端統一的架構
http://blog.nodejitsu.com/scaling-isomorphic-javascript-code前面也評論了幾個答主。 再來回答一下。
首先MVC, MVP和MVVM,這些UI模式的目的是什麼? 就是為了更好的應對,UI需求不斷變化的問題。 聽到「解決需求變化問題」,馬上就應該想到可能需要用設計模式。
各位說說MVC, MVP和MVVM都分別用了什麼設計模式?
他們都用了策略模式和觀察者模式。所以這三種UI模式之間本質上並沒有什麼區別。
View和Control之間是策略模式,Control是View的一種策略。 是View和Model的關係,他們之間是觀察者模式,View在Modle里註冊了數據更新事件。
關鍵的事情來了,MVC, MVP和MVVM他們區別的地方在於: 對觀察模式實現的技術含量上。所有UI模式的終極就是MVVM, 但是由於技術含量問題,對服務程序員的態度問題,可惜的是只有.NET WPF做的最好。其他都是畫虎不成反類犬。
推薦還不懂的同學看看《深入淺出設計模式》---複合模式, 有專門講MVC.
提醒各位,程序員之間的交流請用設計模式,這樣效率最高。
推薦閱讀:
※AngularJS 沒有元素選擇器算不算一個缺點?
※Backbone.js 的最佳應用場景有哪些?
※關於mvc的理解?
※前端 MVC 和伺服器端有哪些差別?