Android 架構(gòu) - MVVM 介紹

前言

只要你掌握了基礎(chǔ)知識(shí),要想構(gòu)建一個(gè)完整的 Android App 并不難牌芋,但是想要寫出一個(gè)可維護(hù)的 App 就是另一回事了蚓炬,這時(shí)候就必須讓你自己的代碼足夠健壯,就需要避免把所有業(yè)務(wù)邏輯代碼都放在 Activity躺屁、Fragment肯夏,或者是創(chuàng)建多個(gè)比較小的只有單一功能的 class。

那么應(yīng)該怎么做呢犀暑?—— 使用 架構(gòu)模式驯击!MVC、MVP耐亏、MVVM徊都、...任何一種都要比沒有架構(gòu)設(shè)計(jì)的流水式代碼好得多,MVVM 是 Android 開發(fā)最好的架構(gòu)選擇之一广辰。Google 官方也非常支持和鼓勵(lì)開發(fā)者使用這一架構(gòu)模式暇矫。

本教程將為你講明白到底什么是 MVVM,雖然我也不喜歡理論择吊,但有時(shí)候在實(shí)際操作之前先了解它非常重要李根,所以請(qǐng)務(wù)必耐心看完。

Model-View-ViewModel 的意義

關(guān)注點(diǎn)分離原則是架構(gòu)的終極原則干发,并且每個(gè)設(shè)計(jì)模式都在盡其所能的實(shí)現(xiàn)這一點(diǎn)朱巨。在 MVVM 中,有 3 個(gè)固定部分有助于實(shí)現(xiàn)關(guān)注點(diǎn)分離:models枉长,viewsview models。你還可以添加一個(gè) repository 琼讽,作為所有數(shù)據(jù)的單一真實(shí)數(shù)據(jù)來源 —— 后面詳細(xì)介紹必峰。

image

View

在 MVVM 中, View 不是指 TextView钻蹬、RecyclerView 這一些控件吼蚁,而是 app 中負(fù)責(zé)處理用戶界面顯示和交互的一個(gè)部分,換一種說法就是问欠,View 負(fù)責(zé)執(zhí)行一切 Activity 或 Fragment 能做的操作肝匆。

這里有一個(gè)重要的概念:View 僅僅處理用戶的即時(shí)交互。什么意思呢顺献?不要把業(yè)務(wù)邏輯比如數(shù)據(jù)庫操作相關(guān)的業(yè)務(wù)放在 Activities 或 Fragments 中旗国。它只負(fù)責(zé)顯示一些東西在屏幕上(比如從 ViewModels 拿到的一些數(shù)據(jù)),執(zhí)行 Android 特定操作并將用戶交互事件(點(diǎn)擊注整、滑動(dòng)等)發(fā)送到各自的 ViewModel能曾。

ViewModel

ViewModel 就像 View 和業(yè)務(wù)邏輯之間的粘合劑度硝,它負(fù)責(zé)從 Repository 獲取數(shù)據(jù)并提供給 View。

當(dāng)你查看上面的架構(gòu)模型圖時(shí)寿冕,你可能想知道 View 如何獲取它應(yīng)該顯示的所有數(shù)據(jù)蕊程。如圖,箭頭僅指向一個(gè)方向 -> ViewModel驼唱。你可能注意到箭頭是單向的藻茂,這意味著 ViewModel 沒有任何關(guān)于哪些 View 正在使用它的線索。雖然這能減少類之間的糾纏玫恳,但是 ViewModel 還是需要告訴 View 需要顯示哪些數(shù)據(jù)辨赐。

這里的做法就是使 ViewModel 中的適當(dāng)數(shù)據(jù)可觀察,通過這樣做纽窟,當(dāng)數(shù)據(jù)更新時(shí)肖油,我們就無需直接從 ViewModel 去更新 View。View 已經(jīng)持有了 ViewModel 的引用臂港,因此它可以方便的觀察 ViewModel 公開的一些數(shù)據(jù)森枪。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),所有觀察它的 View 都將收到相應(yīng)的更改通知(onChange() 被回調(diào))审孽。

image

上述一系列操作可以通過 LiveData 來完成县袱,LiveData 是一個(gè)方便的生命周期感知庫,用于創(chuàng)建可觀察對(duì)象佑力。它的一個(gè)優(yōu)點(diǎn)就是當(dāng) Activity 或 Fragment 已經(jīng)銷毀時(shí)式散,它就不會(huì)自動(dòng)向其發(fā)送通知了,這樣就無需我們自己去管理生命周期了打颤。

Model

Model 就是你放置所有特定業(yè)務(wù)代碼的地方暴拄,雖然從技術(shù)上講,ViewModel 和 Model 之間存在一個(gè)以 Repository 形式存在的中間步驟编饺,你可以將 Repository 中的所有內(nèi)容視為遠(yuǎn)離用戶界面的一組類乖篷。它負(fù)責(zé)從本地?cái)?shù)據(jù)庫或網(wǎng)絡(luò)中獲取數(shù)據(jù)并操作應(yīng)用中的數(shù)據(jù)。

Repository 具有本地存儲(chǔ)和服務(wù)器之間的中介這么一個(gè)特殊角色透且,你可以在此檢查是否應(yīng)該在本地緩存遠(yuǎn)程數(shù)據(jù)等撕蔼。Repository 也是 ViewModel 的單一真實(shí)數(shù)據(jù)來源。也就是說秽誊,當(dāng) ViewModel 想取一些數(shù)據(jù)鲸沮,它就從 Repository 拿,然后由 Repository 決定下一步該做什么锅论,對(duì)于 ViewModel 來說讼溺,數(shù)據(jù)可以從本地、網(wǎng)絡(luò)棍厌、緩存肾胯、…任何地方拿竖席,它并不關(guān)心這些 —— 這是 Repository 應(yīng)該處理的業(yè)務(wù)邏輯。

MVVM 組件的連接性

View 不僅觀察 ViewModel 中的數(shù)據(jù)敬肚,而且 ViewModel 還觀察 Repository 中的數(shù)據(jù)毕荐,后者又觀察來自本地?cái)?shù)據(jù)庫和遠(yuǎn)程數(shù)據(jù)源的數(shù)據(jù)。

為了全面考慮這一點(diǎn)艳馒,你可以通過以下方式考慮 Model憎亚,View,ViewModel弄慰,Repository 和其他類之間的聯(lián)系第美。

遍歷層次結(jié)構(gòu)時(shí),上層類直接引用其子級(jí)陆爽。另一方面什往,子級(jí)不持有其父級(jí)引用。子級(jí)只允許通過 LiveData 或任何其他庫觀察一些數(shù)據(jù)慌闭。

為了便于理解别威,請(qǐng)看下面的箭頭圖。我想在開始時(shí)為你省去不必要的混亂驴剔,這就是為什么那些可觀察到的箭頭沒有出現(xiàn)在介紹 MVVM 的第一個(gè)圖表中省古。

image

這里要提到的最后一件重要事情是你應(yīng)該始終遵守上面的參考樹圖,例如丧失,不要讓你的 ViewModel 繞過 Repository 直接從數(shù)據(jù)庫取數(shù)據(jù)豺妓!一切都有它的目的:使代碼模塊化,易于維護(hù)和閱讀等布讹。你今后讀代碼的時(shí)間永遠(yuǎn)大于寫代碼琳拭,所以代碼的可讀性要放在第一位,不要懶得去抽離和構(gòu)建代碼描验,以后的你會(huì)感謝當(dāng)初的自己的臀栈。

總結(jié)

在這篇文章中,你了解了MVVM架構(gòu)模式背后的概念挠乳,再加上你已經(jīng)掌握的基礎(chǔ)開發(fā)知識(shí),你可以使用這種模式構(gòu)建一個(gè)真正的可維護(hù)的應(yīng)用程序了姑躲,還等什么睡扬?開始行動(dòng)吧??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市黍析,隨后出現(xiàn)的幾起案子卖怜,更是在濱河造成了極大的恐慌,老刑警劉巖阐枣,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件马靠,死亡現(xiàn)場(chǎng)離奇詭異奄抽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)甩鳄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門逞度,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妙啃,你說我怎么就攤上這事档泽。” “怎么了揖赴?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵馆匿,是天一觀的道長。 經(jīng)常有香客問我燥滑,道長渐北,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任铭拧,我火速辦了婚禮赃蛛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羽历。我一直安慰自己焊虏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布秕磷。 她就那樣靜靜地躺著诵闭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澎嚣。 梳的紋絲不亂的頭發(fā)上疏尿,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音易桃,去河邊找鬼褥琐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晤郑,可吹牛的內(nèi)容都是我干的敌呈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼造寝,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼磕洪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起诫龙,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤析显,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后签赃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谷异,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡分尸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歹嘹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箩绍。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荞下,靈堂內(nèi)的尸體忽然破棺而出伶选,到底是詐尸還是另有隱情,我是刑警寧澤尖昏,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布仰税,位于F島的核電站,受9級(jí)特大地震影響抽诉,放射性物質(zhì)發(fā)生泄漏陨簇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一迹淌、第九天 我趴在偏房一處隱蔽的房頂上張望河绽。 院中可真熱鬧,春花似錦唉窃、人聲如沸耙饰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苟跪。三九已至,卻和暖如春蔓涧,著一層夾襖步出監(jiān)牢的瞬間件已,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國打工元暴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篷扩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓茉盏,卻偏偏與公主長得像鉴未,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸠姨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容