1. 程式人生 > >MVC,MVP,MVVM設計模式的比較

MVC,MVP,MVVM設計模式的比較

1. MVC設計模式

1.1 概述

mvc

意義 說明
M Model,表示模型層,資料模型或業務模型,就是我們要顯示給使用者檢視的內容
V View,表示檢視層,就是使用者直接看到的介面,例如:Activity,Fragment,自定義View,還有XML佈局檔案
C Controler,表示控制層,用於模型和檢視間切換資料,對應於Activity業務邏輯,資料處理和UI處理

而J2EE中的MVC分別表示:

  • M:javabean
  • V:jsp
  • C:servlet

三角關係的問題就是維護問題。在MVC,當你有變化的時候你需要同時維護三個物件和三個互動,這顯然讓事情複雜化了

Android中經常會出現數千行的Activity程式碼,究其原因,Android中純粹作為View的各個XML檢視功能太弱,Activity基本上都是View和Controller的合體,既要負責檢視的顯示又要加入控制邏輯,承擔的功能過多,程式碼量大也就不足為奇。所以更貼切的目前常規的開發說應該是View-Model 模式,大部分都是通過Activity的協調,連線,和處理邏輯的

Activity中存在兩部分內容:業務相關和介面相關,V中的內容較少,而C中的內容較多
解決方案:將Activity中的業務部分拆分—-MVP,將Activity中的介面部分拆分—-MVVM

1.2 案例分析

Android中的ListView就用到了MVC設計模式

  • M:資料的集合,List
  • V:ListView
  • C:Adapter,控制資料如何顯示在ListView上

而Activity控制層和檢視層都有

2. MVP設計模式

mvp模式

意義 說明
Model 依然是實體模型
View 對應於Activity和xml,負責View的繪製以及與使用者互動
Presenter 負責完成View於Model間的互動和業務邏輯

利用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層太大,程式碼臃腫的問題。

切斷的View和Model的聯絡,讓View只和Presenter(原Controller)互動,減少在需求變化中需要維護的物件的數量。MVP定義了Presenter和View之間的介面,讓一些可以根據已有的介面協議去各自分別獨立開發,以此去解決介面需求變化頻繁的問題

MVP模式是MVC模式的一個演化版本,MVP全稱Model-View-Presenter。目前MVP在Android應用開發中越來越重要了。解耦view和model層

在Android中,業務邏輯和資料存取是緊緊耦合的,很多缺乏經驗的開發者很可能會將各種各樣的業務邏輯塞進某個Activity、Fragment或者自定義View中,這樣會使得這些元件的單個型別臃腫不堪。如果不將具體的業務邏輯抽離出來,當UI變化時,你就需要去原來的View中抽離具體業務邏輯,這必然會很麻煩並且易出錯。

對於view層和presenter層的通訊,我們是可以通過介面實現的,具體的意思就是說我們的activity,fragment可以去實現實現定義好的介面,而在對應的presenter中通過介面呼叫方法。

將activity中的業務部分拆分—mvp,使用介面實現view和presenter的通訊和隔離,這種方式有一個缺點,就是介面會非常多

將activity中的介面相關內容拆分—mvvm

2.1 使用MVP的好處

MVP模式會解除View與Model的耦合,有效的降低View的複雜性。同時又帶來了良好的可擴充套件性、可測試性,保證系統的整潔性和靈活性。

MVP模式可以分離顯示層與邏輯層,它們之間通過介面進行通訊,降低耦合。理想化的MVP模式可以實現同一份邏輯程式碼搭配不同的顯示介面,因為它們之間並不依賴於具體,而是依賴於抽象。這使得Presenter可以運用於任何實現了View邏輯介面的UI,使之具有更廣泛的適用性,保證了靈活度。

2.2 MVP模式的三個角色

  • Presenter – 互動中間人

Presenter主要作為溝通View與Model的橋樑,它從Model層檢索資料後,返回給View層,使得View與Model之間沒有耦合,也將業務邏輯從View角色上抽離出來。負責完成View於Model間的互動和業務邏輯

  • View – 使用者介面

View通常是指Activity、Fragment或者某個View控制元件,它含有一個Presenter成員變數。通常View需要實現一個邏輯介面,將View上的操作轉交給Presenter進行實現,最後,Presenter 呼叫View邏輯介面將結果返回給View元素。對應於Activity和xml,負責View的繪製以及與使用者互動

  • Model – 資料的存取

Model 角色主要是提供資料的存取功能。Presenter 需要通過Model層儲存、獲取資料,Model就像一個數據倉庫。更直白的說,Model是封裝了資料庫DAO或者網路獲取資料的角色,或者兩種資料方式獲取的集合。

3. MVVM設計模式

mvvm模式

意義 說明
Model 實體模型,代表基本業務邏輯
View 對應於Activity和xml,負責View的繪製以及與使用者互動
ViewModel 將view和model聯絡在一起,起到橋樑的作用,負責完成View於Model間的互動,負責業務邏輯

MVVM的目標和思想MVP類似,利用資料繫結(Data Binding)、依賴屬性(Dependency Property)、命令(Command)、路由事件(Routed Event)等新特性,打造了一個更加靈活高效的架構。

ViewModel大致上就是MVP的Presenter和MVC的Controller了,而View和ViewModel間沒有了MVP的介面介面,而是直接互動,用資料“繫結”的形式讓資料更新的事件不需要開發人員手動去編寫特殊用例,而是自動地雙向同步。比起MVP,MVVM不僅簡化了業務與介面的依賴關係,還優化了資料頻繁更新的解決方案,甚至可以說提供了一種有效的解決模式。

可以直接在layout佈局xml中繫結資料,分離檢視與業務邏輯,低耦合,可重用,獨立開發,可測試

View的變化可以自動的反應在ViewModel,ViewModel的資料變化也會自動反應到View上,data binding框架解決了資料繫結的問題

  • 資料驅動

在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原生開發的從業者受的的衝擊會更大。