Android三大項目架構MVC、MVP、MVVM使用體驗

本文由業鬆所寫,轉載請註明作者。

先上個鏈接吧,谷歌官方github的Android架構demo,裏面有各種各樣的MVP、MVVM架構,可以clone下來自己新建項目的時候作參考。clone後需要切換branch才能看到其他架構的代碼。
今年MVC、MVP、MVVM都有寫,其中MVVM以前沒接觸過,現在終於可以談談這三種架構的使用感受了。由於今年寫的Android項目都是商業的,沒寫個人項目,代碼貼不了(可以說純幹聊,無干貨- -)。

子虛烏有的MVC(Model-View-Controller)

爲什麼說Android MVC架構子虛烏有?MVC分層概念是在Java後臺Spring框架裏拿過來的。人家的Controller和View層代碼確實是分離的。Android裏面哪裏分了,對此我斗膽做個猜測:在發明Android-MVP架構的時候,大家不知道怎麼稱呼原始的Android架構,於是強行從Spring那裏拿了個MVC的名字把它和MVP區分開來。

Controller層的本意是處理事件的分發和響應,把Activity看作Controller層也不是不可以,但是既然View和Controller並沒有分層,沒必要牽強附會到MVC上去。

所以所謂的MVC在Android裏就是沒有分層架構的意思。沒有分層的架構是不是就一定不好呢?當然不是,別說小型應用,就是谷歌自己寫的應用也有好幾千行代碼一個Activity好幾千行代碼擼到底的呢(想找個例子來着,發現最新版本的aosp裏Activity和Fragment代碼都精簡了不少)。

在代碼領域很多事情不是非此即彼,我見過不少商業項目有着各種架構、設計模式還有封裝好的基類,最後Presenter裏就幾行代碼甚至一行代碼都沒有。因此對於小項目,Activity裏的代碼不重的話,沒必要各種分層。對於可能會寫成大項目的項目,也可以先不分層,後續該重構的時候再重構。真的要一個Activity幾千行的話肯定是不建議的,閱讀性太差,定位、修改起來也十分困難。

商業項目廣泛使用的MVP(Model-View-Presenter)

MVP架構在Android領域可謂十分成熟,我見過的商業項目很多都喜歡用MVP架構。好處自然不用多說,把與UI無關的邏輯代碼全部抽出來放到Presenter層裏,用接口明確定義好View層和Presenter層的功能。這樣的話架構層次清晰,閱讀和修改起來要容易得多。

不過使用MVP架構的項目往往會有過度封裝的傾向。基本上都會封裝有BaseActivity、BaseFragment、BasePresenter,BaseView、BaseModel等等。封裝可以讓我們更多地複用代碼,少寫重複代碼。但是封裝是不是百利而無一害呢?當然不是,封裝有時候會犧牲代碼的靈活性。比如在基類裏定義了太多類的行爲,子類想要修改就只能複寫。但是可能一個地方例外,所以地方都變得不一樣,封裝的太死的話很多地方都要重寫。因此基類的東西應該只有確定所有子類都一致的東西,不要試圖把所有的東西都塞到基類裏。我當時所在的一個項目用的mvp‑dagger架構,新建一個Fragment大概要添加/修改七八個類,不得不說真的挺費勁的。

毫無疑問,MVP給Android帶來了代碼分層的概念,確實是一個很好的實踐。但是在使用MVP之前先考慮一下自己能不能接受一個頁面至少要寫四五個類- -

最“流行”的MVVM(Model-View-ViewModel)

爲啥流行加了雙引號呢,因爲在Android領域還是MVP最流行,而在Javascript前端領域,Angular、Vue、React都是MVVM架構。所以MVVM是真的火到爆炸。至於爲什麼Android MVVM還不是很流行呢(起碼我身邊很多同行都沒用過,我也是今年才真正用過)?之前和微信羣裏的一個網友討論過,我覺得他說的很有道理:前幾年Android開發火熱的時候MVP架構應運而生,人人面試都要談MVP。而今更新一代的MVVM架構出來後,Android開發市場早已冷卻,大家沒有動力去切換新的設計模式,畢竟哪怕啥架構模式也沒有不也一樣能開發大型項目麼?

MVP和MVVM有啥區別呢?我也看過很多文章,不過talk is cheap,看再多還是要真正去實踐才能感受MVVM架構的好用之處,也明白了爲什麼三大JS前端框架都用這種架構。

MVP和MVVM區別就是P和VM區別。Presenter層是把UI無關的邏輯自己處理掉,最後把處理完的數據傳輸給View層展示;ViewModel是把Model和View層關聯起來的一箇中間層,讓View層可以響應式地展示數據。在我看來,VM的核心思想就是UI回調。View層通過ViewModel可以直接動態地展示數據,我們不需要在數據改變時去回調UI,這樣可以省去非常非常多的UI代碼,怪不得前端都喜歡MVVM。

Android MVVM的實現方式主要有兩種,一種是給數據加監聽,比如使用LiveData,在數據變化時執行監聽的回調,這樣就不需要每次改變數據後再手動地修改UI。第二種就是[DataBinding]{https://developer.android.com/topic/libraries/data-binding/}框架了。在layout xml裏面定義Observable數據,然後直接把數據塞給控件。通常我們會把要展示的最終數據封裝到ViewModel層代碼裏。而且在xml裏也能對數據進行簡單的操作,具體數據操作大家在這裏查到。

MVP並沒有真正減少代碼,只是把代碼做了分層。而MVVM不但讓代碼分層的更加乾淨,還減少了大量的UI回調代碼。因此用過MVVM之後我就愛上了它,相信你也一樣!

關於Model層

從寫MVP代碼開始我就在想,Model層到底是個啥?很多人把Model層翻譯爲數據層,可是Model是模型的意思啊。Model是不是隻包括Model類,還是包含數據增刪改查所有代碼,我一直在想這個問題。而且我問過不少人看過不少文章,各種看法都有。

在上面的googlesamples,很多架構的M層是包含數據的獲取的,並且會封裝到XXXRepository類裏。這樣做的好處就是保證數據來源的唯一性(前端數據層框架Redux三大原則第一條就是Single source of truth)。而在SpringMVC裏面,pojo數據的增刪改查被封裝到dao層,業務處理會封裝到service層。因此大型架構的數據的操作基本上都會進行封裝,這點沒有疑問。至於這些repository、dao、service層屬於Model層還是Presenter層還是另外一個層面,可以看看Wiki上關於MVC的定義

The model is the central component of the pattern. It is the application's dynamic data structure, independent of the user interface.It directly manages the data, logic and rules of the application.

從這段話可以看出來dao層,repository層確實屬於Model層,至於更進一步的業務處理,則不屬於Model層(比如在MVP裏就是P層)。

最後歡迎大家多多交流,不吝指點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章