相信你們對MVC,MVP和MVVM都不陌生,做爲三個最耳熟能詳的Android框架,它們的應用能夠是很是普遍的,可是對於一些新手來講,可能對於區分它們三個都有困難,更別說在實際的項目中應用了,有些時候想用MVP的,代碼寫着寫着就變成了MVC,長此以往就對它們三個的選擇產生了恐懼感,若是你也是這樣的人羣,那麼這篇文章可能會對你有很大的幫助,但願你們看完都會有收穫吧!php
文章重點:java
(1)瞭解並區分MVC,MVP,MVVM。git
(2)知道這三種模式在Android中如何使用。程序員
(3)走出data binding的誤區。github
(4)瞭解MVP+data binding的開發模式。網絡
本篇文章的demo我將會上傳到個人github上。架構
正如莊子在逍遙遊中說的,若是水不夠深,那就沒有可以擔負大船的力量 。因此在真正開始涉及具體的代碼以前,咱們要先對MVC,MVP和MVVM作一個初步的瞭解。若是各位同窗對此已經有所瞭解了,能夠選擇性跳過這一節。mvc
MVC,Model View Controller,是軟件架構中最多見的一種框架,簡單來講就是經過controller的控制去操做model層的數據,而且返回給view層展現,具體見下圖框架
當用戶出發事件的時候,view層會發送指令到controller層,接着controller去通知model層更新數據,model層更新完數據之後直接顯示在view層上,這就是MVC的工做原理。mvvm
那具體到Android上是怎麼樣一個狀況呢?
你們都知道一個Android工程有什麼對吧,有java的class文件,有res文件夾,裏面是各類資源,還有相似manifest文件等等。對於原生的Android項目來講,layout.xml裏面的xml文件就對應於MVC的view層,裏面都是一些view的佈局代碼,而各類java bean,還有一些相似repository類就對應於model層,至於controller層嘛,固然就是各類activity咯。你們能夠試着套用我上面說的MVC的工做原理是理解。好比你的界面有一個按鈕,按下這個按鈕去網絡上下載一個文件,這個按鈕是view層的,是使用xml來寫的,而那些和網絡鏈接相關的代碼寫在其餘類裏,好比你能夠寫一個專門的networkHelper類,這個就是model層,那怎麼鏈接這兩層呢?是經過button.setOnClickListener()這個函數,這個函數就寫在了activity中,對應於controller層。是否是很清晰。
你們想過這樣會有什麼問題嗎?顯然是有的,否則爲何會有MVP和MVVM的誕生呢,是吧。問題就在於xml做爲view層,控制能力實在太弱了,你想去動態的改變一個頁面的背景,或者動態的隱藏/顯示一個按鈕,這些都沒辦法在xml中作,只能把代碼寫在activity中,形成了activity既是controller層,又是view層的這樣一個窘境。你們回想一下本身寫的代碼,若是是一個邏輯很複雜的頁面,activity或者fragment是否是動輒上千行呢?這樣不只寫起來麻煩,維護起來更是噩夢。(固然看過Android源碼的同窗其實會發現上千行的代碼不算啥,一個RecyclerView.class的代碼都快上萬行了呢。。)
MVC還有一個重要的缺陷,你們看上面那幅圖,view層和model層是相互可知的,這意味着兩層之間存在耦合,耦合對於一個大型程序來講是很是致命的,由於這表示開發,測試,維護都須要花大量的精力。
正由於MVC有這樣那樣的缺點,因此才演化出了MVP和MVVM這兩種框架。
MVP做爲MVC的演化,解決了MVC很多的缺點,對於Android來講,MVP的model層相對於MVC是同樣的,而activity和fragment再也不是controller層,而是純粹的view層,全部關於用戶事件的轉發所有交由presenter層處理。下面仍是讓咱們看圖
從圖中就能夠看出,最明顯的差異就是view層和model層再也不相互可知,徹底的解耦,取而代之的presenter層充當了橋樑的做用,用於操做view層發出的事件傳遞到presenter層中,presenter層去操做model層,而且將數據返回給view層,整個過程當中view層和model層徹底沒有聯繫。看到這裏你們可能會問,雖然view層和model層解耦了,可是view層和presenter層不是耦合在一塊兒了嗎?其實不是的,對於view層和presenter層的通訊,咱們是能夠經過接口實現的,具體的意思就是說咱們的activity,fragment能夠去實現實現定義好的接口,而在對應的presenter中經過接口調用方法。不只如此,咱們還能夠編寫測試用的View,模擬用戶的各類操做,從而實現對Presenter的測試。這就解決了MVC模式中測試,維護難的問題。
固然,其實最好的方式是使用fragment做爲view層,而activity則是用於建立view層(fragment)和presenter層(presenter)的一個控制器。
MVVM最先是由微軟提出的
這裏要感謝泡在網上的日子,由於前面看到的三張圖我都是從它的博客中摘取的,若是有人知道不容許這樣作的話請告訴我,我會從個人博客中刪除的,謝謝。
從圖中看出,它和MVP的區別貌似不大,只不過是presenter層換成了viewmodel層,還有一點就是view層和viewmodel層是相互綁定的關係,這意味着當你更新viewmodel層的數據的時候,view層會相應的變更ui。
咱們很難去說MVP和MVVM這兩個MVC的變種孰優孰劣,仍是要具體狀況具體分析。
對於程序員來講,空談是最沒效率的一種方式,相信你們看了我上面對於三種模式的分析,或多或少都會有點雲裏霧裏,下面讓咱們結合代碼來看看。
讓咱們試想一下下面這個情景,用戶點擊一個按鈕A,獲取github上對應公司對應倉庫中貢獻排行第一的任的名字,而後咱們還會有一個按鈕B,用戶點擊按鈕B,界面上排行第一的那我的的名字就會換成本身的。