一篇文章告訴你MVC&MVP&MVVM
一個人善於使用模式,相當於把一些特定問題進行了抽象概括,大腦其實可以騰出更大的空間處理別的事情(具體的業務等)。所以,這一兩年我也比較喜歡嘗試使用一些流行的模式或者開源框架到自己的專案中,最終不一定會投入使用,但嘗試的過程還是很有益處的。今天我們就把開發當中常用的模式簡單介紹一下。來小可愛,上車吧!

Picture
MVC
MVC全名是Model--View--Controller,是模型(model)-檢視(view)-控制器(controller)的縮寫,一種軟體設計典範,用一種業務邏輯、資料、介面顯示分離的方法組織程式碼,在改進和個性化定製介面及使用者互動的同時,不需要重新編寫業務邏輯。其中Model層處理資料,業務邏輯等;View層處理介面的顯示結果;Controller層起到橋樑的作用,來控制View層和Model層通訊以此來達到分離檢視顯示和業務邏輯層。

Picture
我們往往把Android中介面部分的實現也理解為採用了MVC框架,常常把Activity理解為MVC模式中的Controller。
看似沒有什麼特別的地方,但是由幾個需要特別關注的關鍵點:
1、View是把控制權交移給Controller,自己不執行業務邏輯。
2、Controller執行業務邏輯並且操作Model,但不會直接操作View,可以說它是對View無知的。
3、View和Model的同步訊息是通過觀察者模式進行,而同步操作是由View自己請求Model的資料然後對檢視進行更新。
MVC的優缺點
-
優點:
1、把業務邏輯全部分離到Controller中,模組化程度高。當業務邏輯變更的時候,不需要變更View和Model,只需要Controller換成另外一個 Controller就行了(Swappable Controller)。 2、觀察者模式可以做到多檢視同時更新。
-
缺點:
1、Controller測試困難。因為檢視同步操作是由View自己執行,而View只能在有UI的環境下執行。在沒有UI環境下對Controller進行單元測試的時候, Controller業務邏輯的正確性是無法驗證的:Controller更新Model的時候,無法對View的更新操作進行斷言。 2、View無法元件化。View是強依賴特定的Model的,如果需要把這個View抽出來作為一個另外一個應用程式可複用的元件就困難了。 因為不同程式的的Domain Model是不一樣的
MVP
MVP其實是MVC的一種演進版本,它更簡單,將MVC中的Controller改為了Presenter,View通過介面與Presenter進行互動,降低耦合,方便進行單元測試。
View:負責繪製UI元素、與使用者進行互動(Activity、View、Fragment都可以做為View層);
Model:對資料的操作、對網路等的操作,和業務相關的邏輯處理;
Presenter:作為View與Model互動的中間紐帶,處理與使用者互動的邏輯。可以把Presenter理解為一箇中間層的角色,它接受Model層的資料,並且處理之後傳遞給View層,還需要處理View層的使用者互動等操作。

Picture
關鍵點:
1、View不再負責同步的邏輯,而是由Presenter負責。Presenter中既有業務邏輯也有同步邏輯。 2、View需要提供操作介面的介面給Presenter進行呼叫。(關鍵)
對比在MVC中,Controller是不能操作View的,View也沒有提供相應的介面;而在MVP當中,Presenter可以操作View,View需要提供一組對介面操作的介面給Presenter進行呼叫;Model仍然通過事件廣播自己的變更,但由Presenter監聽而不是View。
MVP(Passive View)的優缺點
-
優點:
1、便於測試。Presenter對View是通過介面進行,在對Presenter進行不依賴UI環境的單元測試的時候。可以通過Mock一個View物件,這個物件只需要實現了View的介面即可。然後依賴注入到Presenter中,單元測試的時候就可以完整的測試Presenter業務邏輯的正確性。 2、View可以進行元件化。在MVP當中,View不依賴Model。這樣就可以讓View從特定的業務場景中脫離出來,可以說View可以做到對業務邏輯完全無知。它只需要提供一系列介面提供給上層操作。這樣就可以做高度可複用的View元件。
-
缺點:
1、Presenter中除了業務邏輯以外,還有大量的View->Model,Model->View的手動同步邏輯,造成Presenter比較笨重,維護起來會比較困難。
MVVM
MVVM模式(Model--View--ViewModel模式),和MVP模式相比,MVVM 模式用ViewModel替換了Presenter ,其他層基本上與 MVP 模式一致,ViewModel可以理解成是View的資料模型和Presenter的合體。
MVVM採用雙向繫結(data-binding):View的變動,自動反映在ViewModel,反之亦然,這種模式實際上是框架替應用開發者做了一些工作(相當於ViewModel類是由庫幫我們生成的),開發者只需要較少的程式碼就能實現比較複雜的互動。

Picture
MVVM的呼叫關係
MVVM的呼叫關係和MVP一樣。但是,在ViewModel當中會有一個叫Binder,或者是Data-binding engine的東西。以前全部由Presenter負責的View和Model之間資料同步操作交由給Binder處理。你只需要在View的模版語法當中,指令式地宣告View上的顯示的內容是和Model的哪一塊資料繫結的。當ViewModel對進行Model更新的時候,Binder會自動把資料更新到View上去,當用戶對View進行操作(例如表單輸入),Binder也會自動把資料更新到Model上去。這種方式稱為:Two-way data-binding,雙向資料繫結。可以簡單而不恰當地理解為一個模版引擎,但是會根據資料變更實時渲染。
關鍵點:
MVVM把View和Model的同步邏輯自動化了。以前Presenter負責的View和Model同步不再手動地進行操作,而是交由框架所提供的Binder進行負責。 只需要告訴Binder,View顯示的資料對應的是Model哪一部分即可。
MVVM的優缺點
-
優點:
1、提高可維護性。解決了MVP大量的手動View和Model同步的問題,提供雙向繫結機制。提高了程式碼的可維護性。 2、簡化測試。因為同步邏輯是交由Binder做的,View跟著Model同時變更,所以只需要保證Model的正確性,View就正確。大大減少了對View同步更新的測試。
-
缺點:
1、過於簡單的圖形介面不適用,或說牛刀殺雞。 2、對於大型的圖形應用程式,檢視狀態較多,ViewModel的構建和維護的成本都會比較高。 3、資料繫結的宣告是指令式地寫在View的模版當中的,這些內容是沒辦法去打斷點debug的。
結語
可以看到,從MVC->MVP->MVVM,就像一個打怪升級的過程。後者解決了前者遺留的問題,把前者的缺點優化成了優點。同樣的Demo功能,程式碼從最開始的一堆檔案,優化成了最後只需要20幾行程式碼就完成。MV*模式之間的區分還是蠻清晰的,希望可以給對這些模式理解比較模糊的同學帶來一些參考和思路。

image

image