「Android 架構」—— MVVM 詳解
前言
只要你掌握了基礎知識,要想構建一個完整的 Android App 並不難,但是想要寫出一個 可維護 的 App 就是另一回事了,這時候就必須讓你自己的程式碼足夠健壯,就需要避免把所有業務邏輯程式碼都放在 Activity、Fragment,或者是建立多個比較小的只有單一功能的 class。
那麼應該怎麼做呢?—— 使用 架構模式! MVC、MVP、 MVVM 、...任何一種都要比沒有架構設計的流水式程式碼好得多,MVVM 是 Android 開發最好的架構選擇之一。Google 官方也非常支援和鼓勵開發者使用這一架構模式。
本教程將為你講明白到底什麼是 MVVM,雖然我也不喜歡理論,但有時候在實際操作之前先了解它非常重要,所以請務必耐心看完。
Model-View-ViewModel 的意義
關注點分離原則 是架構的終極原則,並且每個設計模式都在盡其所能的實現這一點。在 MVVM 中,有 3 個固定部分有助於實現關注點分離: models
, views
和 view models
。你還可以新增一個 repository
,作為所有資料的 單一真實資料來源 —— 後面詳細介紹。

image
View
在 MVVM 中, View 不是指 TextView
、 RecyclerView
這一些控制元件,而是 app 中負責處理使用者介面顯示和互動的一個部分,換一種說法就是,View 負責執行一切 Activity 或 Fragment 能做的操作。
這裡有一個重要的概念: View 僅僅處理使用者的即時互動 。什麼意思呢?不要把業務邏輯比如資料庫操作相關的業務放在 Activities 或 Fragments 中。它只負責顯示一些東西在螢幕上(比如從 ViewModels 拿到的一些資料),執行 Android 特定操作並將使用者互動事件(點選、滑動等)傳送到各自的 ViewModel。
ViewModel
ViewModel 就像 View 和業務邏輯之間的粘合劑,它負責從 Repository 獲取資料並提供給 View。
當你檢視上面的架構模型圖時,你可能想知道 View 如何獲取它應該顯示的所有資料。如圖,箭頭僅指向一個方向 -> ViewModel。你可能注意到箭頭是單向的,這意味著 ViewModel 沒有任何關於哪些 View 正在使用它的線索 。雖然這能減少類之間的糾纏,但是 ViewModel 還是需要告訴 View 需要顯示哪些資料。
這裡的做法就是使 ViewModel 中的適當資料可觀察,通過這樣做,當資料更新時,我們就無需直接從 ViewModel 去更新 View。View 已經持有了 ViewModel 的引用,因此它可以方便的觀察 ViewModel 公開的一些資料。當資料發生變化時,所有觀察它的 View 都將收到相應的更改通知(onChange() 被回撥)。

image
上述一系列操作可以通過 LiveData 來完成,LiveData 是一個方便的生命週期感知庫,用於建立可觀察物件。它的一個優點就是當 Activity 或 Fragment 已經銷燬時,它就不會自動向其傳送通知了,這樣就無需我們自己去管理生命週期了。
Model
Model 就是你放置所有特定業務程式碼的地方,雖然從技術上講,ViewModel 和 Model 之間存在一個以 Repository 形式存在的中間步驟,你可以將 Repository 中的所有內容視為遠離使用者介面的一組類。它負責從本地資料庫或網路中獲取資料並操作應用中的資料。
Repository 具有本地儲存和伺服器之間的中介這麼一個特殊角色,你可以在此檢查是否應該在本地快取遠端資料等。Repository 也是 ViewModel 的 單一真實資料來源 。也就是說,當 ViewModel 想取一些資料,它就從 Repository 拿,然後由 Repository 決定下一步該做什麼,對於 ViewModel 來說,資料可以從本地、網路、快取、…任何地方拿,它並不關心這些 —— 這是 Repository 應該處理的業務邏輯。
MVVM 元件的連線性
View 不僅觀察 ViewModel 中的資料,而且 ViewModel 還觀察 Repository 中的資料,後者又觀察來自本地資料庫和遠端資料來源的資料。
為了全面考慮這一點,你可以通過以下方式考慮 Model,View,ViewModel,Repository 和其他類之間的聯絡。
遍歷層次結構時,上層類直接引用其子級。另一方面,子級不持有其父級引用。如果您願意,子級只允許通過 LiveData 或任何其他庫觀察一些資料。
為了便於理解,請看下面的箭頭圖。我想在開始時為你省去不必要的混亂,這就是為什麼那些可觀察到的箭頭沒有出現在介紹 MVVM 的第一個圖表中。

image
這裡要提到的最後一件重要事情是你應該 始終遵守上面的參考樹圖 ,例如,不要讓你的 ViewModel 繞過 Repository 直接從資料庫取資料!一切都有它的目的:使程式碼模組化,易於維護和閱讀等。你今後讀程式碼的時間永遠大於寫程式碼,所以程式碼的可讀性要放在第一位,不要懶得去抽離和構建程式碼,以後的你會感謝當初的自己的。
總結
在這篇文章中,你瞭解了MVVM架構模式背後的概念。現在您已經掌握了基礎知識,快開始使用這種模式構建一個真正的應用程式吧:sunglasses: