原文地址:
????https://blog.mindorks.com/essential-guide-for-designing-your-android-app-architecture-mvp-part-1-74efaf1cda40#.lkml1yggq
大多數(shù)人開始創(chuàng)建一個(gè) Android APP 時(shí)會(huì)決定它的核心活動(dòng)和能力以及如何去獲取數(shù)據(jù)。代碼會(huì)在一個(gè)又一個(gè)周期內(nèi)發(fā)展始绍,繼而成為一系列不可重用的組件舌镶。我們開始打包這些組件蝉揍,并在 Activity 中通過 api 來使用組件舀武。我們覺得這種做法很優(yōu)秀并開始將代碼盡可能地打碎邻辉,直至我們沉浸在組件的海洋中才發(fā)現(xiàn)難以找到所需要的組件并使用轿衔。如果你有編寫測試代碼微驶,我們稍后將介紹可測試的概念和如何更安全地回退代碼浪谴。我們在 Android api 耦合性非常緊密的地方進(jìn)行開發(fā)會(huì)感覺代碼變得一團(tuán)糟,這會(huì)防止我們?nèi)プ?JVM 的測試和阻礙測試用例的簡單設(shè)計(jì)因苹。這就是 Activity 或 Fragment 作為控制器的經(jīng)典 MVC 模式苟耻。
所以,我們制定了解決上述的絕大多數(shù)問題但是實(shí)現(xiàn)起來需要很小心的原則扶檐。這些原則凶杖,我們稱之為MVP設(shè)計(jì)模式。
那么到底什么是MVP設(shè)計(jì)模式呢款筑?
MVP設(shè)計(jì)模式是一套分離代碼使其具有重用性和可測試性的指導(dǎo)方針智蝠。劃分應(yīng)用組件以此作為基線,稱其關(guān)注點(diǎn)分離奈梳。
Model:負(fù)責(zé)控制應(yīng)用內(nèi)的數(shù)據(jù)
View:負(fù)責(zé)在屏幕上顯示特殊數(shù)據(jù)的視圖
Presenter:負(fù)責(zé) Model 和 View 之間的連接杈湾,也可扮演 VIEW 的指導(dǎo)者
MVP為上面提及的組件設(shè)定了一些規(guī)則,如下舉例:
界面層唯一的職責(zé)就是在 Presenter 的指揮下繪制 UI攘须。
View 代表所有傳遞給 Presenter 的用戶操作漆撞。
View 層絕不直接與 Model 層溝通。
Presenter 層的職責(zé)是通過特殊事件將 View 層向 Model 發(fā)起請求和 Model 層通過行動(dòng)指導(dǎo) View 層工作。
Model 層負(fù)責(zé)取得來自服務(wù)器浮驳、數(shù)據(jù)庫及文件系統(tǒng)的數(shù)據(jù)悍汛。
以上提到的原則有多種可以實(shí)現(xiàn)的方式。每一位開發(fā)者應(yīng)該有自己對(duì)此的理解至会。概括來說员凝,基本的螺母和螺栓在小改動(dòng)中很常見。
Activity瓶蚂、Fragment和自定義控件在應(yīng)用中應(yīng)為 View 層的部分。
每一個(gè) View 都有一個(gè) Presenter 與其一對(duì)一的關(guān)系宣吱。
View 和它的 Presenter 通訊通過接口進(jìn)行窃这,反之亦然。
Model 層可分為多個(gè)部分:APIHelper征候、PreferenceHelper杭攻、DataBaseHelper和FileHelper。這些所有的Helper都屬于DataManager(數(shù)據(jù)管理者)疤坝,在本質(zhì)上把所有的 Model 部分連接起來兆解。
Presenter 與 DataManager 的通訊通過接口進(jìn)行。
DataManager 只有在請求的時(shí)候才會(huì)執(zhí)行跑揉。
Presenter 不會(huì)有任何 Android 的 api.
現(xiàn)在锅睛,這些信息可以明顯地從任何博客或者M(jìn)VP的安卓規(guī)范中找到。那么這篇文章的要點(diǎn)是什么历谍?
這篇文字是為了解決一個(gè)MVP中重要的挑戰(zhàn)而寫的现拒。如何在整個(gè)應(yīng)用中真正地實(shí)行這些規(guī)范?
MVP展現(xiàn)一個(gè)簡單的 Activity 例子時(shí)顯得非常簡單望侈,但當(dāng)我們嘗試對(duì)應(yīng)用中的所有組件綁定在一次的時(shí)候感到困惑印蔬。
首先我們簡單描繪這種架構(gòu)的藍(lán)圖。
架構(gòu)是你實(shí)現(xiàn)任何軟件第一件想到的事情脱衙。當(dāng)一個(gè)精美的架構(gòu)可以提供穩(wěn)定和可擴(kuò)展性侥猬,它將極大地減少在未來的重復(fù)工作。如今岂丘,大多數(shù)的項(xiàng)目都是以團(tuán)隊(duì)進(jìn)行開發(fā)陵究,因此在這個(gè)架構(gòu)中,最重要的元素為代碼的可讀性和模塊性奥帘。
我們非常依賴第三方庫铜邮,并且由于用例、bug、輔助的原因松蒜,我們不斷在可選方案之間切換扔茅。所以我們的架構(gòu)應(yīng)該被設(shè)計(jì)成即插即用。
這個(gè)安卓架構(gòu)的藍(lán)圖畫在包含所有MVP特性和MVP原則之上秸苗。
下面的內(nèi)容在第一次閱讀可能會(huì)感到被困惑淹沒召娜,但在你貫穿這篇文章整個(gè)下部分的例子,將會(huì)對(duì)這些概念豁然開朗惊楼。
那些渴求知識(shí)的人將得到它玖瘸。
讓我們先來明白每一個(gè)部分在架構(gòu)中的作用。 View: 這個(gè)部分操控UI和接受來自用戶的交互檀咙。由Activity雅倒,F(xiàn)ragment,自定義控件共同組成弧可。 MVPView: 這是一個(gè)借口蔑匣,它被View實(shí)現(xiàn)。它包括一些暴露給Presenter用于通訊的方法棕诵。 Presenter: 這是View層的決策者裁良,它由純Java類構(gòu)成,沒有任何Android 的 API 校套。它接受來自View傳遞過來的用戶交互价脾,同時(shí)它對(duì)最基本的業(yè)務(wù)邏輯起決策作用。最后指揮 View 去執(zhí)行特殊的動(dòng)作笛匙。它也和DataManager通訊彼棍,以獲得處理業(yè)務(wù)邏輯所需要的數(shù)據(jù)。 MVPPresenter: 這是一個(gè)借口膳算,它被Presenter所實(shí)現(xiàn)座硕,它包含一些暴露給View的方法APPDBHelper: 數(shù)據(jù)庫管理和所有關(guān)聯(lián)到數(shù)據(jù)庫的操作在這一部分實(shí)現(xiàn)。 DBHelper: 這是一個(gè)被APPDBHelper 實(shí)現(xiàn)的借口涕蜂,包含暴露給Application組件的方法华匾。這一層將任何特殊的實(shí)現(xiàn)分離,因此使APPDBHelper成為即插即用的單元机隙。 AppPreferenceHelper : 這是一個(gè)類似APPDBHelper 但它的工作是在android sp中讀寫數(shù)據(jù)蜘拉。 PreferenceHelper: 接口層,類似DBHelper有鹿,但是被APPPreferenceHelper所實(shí)現(xiàn)旭旭。 APPAPIHelper: 負(fù)責(zé)管理網(wǎng)絡(luò)層API調(diào)用和控制API數(shù)據(jù)。 APIHelper: 接口層葱跋,類似DBHelper 但被APPAPIHelper所實(shí)現(xiàn)持寄。 DataManager: 這是一個(gè)接口源梭,被APPDataManager所實(shí)現(xiàn)。它包含方法稍味,暴露于所有管理數(shù)據(jù)操作的方法废麻。理想地,它代理提供給所有Helper類的服務(wù)模庐。DataManager借口擴(kuò)展了DBHelper烛愧,PreferenceHelper 和 APIHelper借口。 AppDataManager: 這是一個(gè)涉及任何數(shù)據(jù)相關(guān)操作的接口掂碱。DBHelper怜姿,PreferenceHelper和APIHelper只為DataManager工作。它將所有特定的操作委托給每一個(gè)Helper疼燥。
現(xiàn)在社牲,我們熟悉了所有的組件以及他們在Application中的角色。我們現(xiàn)在為各種不同組件規(guī)劃溝通模式悴了。 Application類的實(shí)例化APPDBHelper,APPPreferenceHelper违寿,APPAPIHelper和APPDataManager湃交,方法是向它傳遞DbHelper, PreferenceHelper 和Helper的引用。 View 組件的實(shí)例是Presenter通過MVPPresenter 的引用藤巢。 Presenter接受他的View組件和通過MVPView操控它搞莺,Presenter也接受DataManager。 DataManager是單例掂咒。
這是application 實(shí)現(xiàn)MVP的基本方針才沧。
就像一個(gè)外科醫(yī)生教授所有的外科程序,不會(huì)有任何用處绍刮,直至它真正執(zhí)行和練習(xí)它温圆。我們不能理解這些idea直至我們真正去使用它。
在下一個(gè)章節(jié)孩革,我們將探索一個(gè)真實(shí)的APP例子和有希望去明白和很好地理解這些概念岁歉。
在第一個(gè)章節(jié),我們介紹了MVP的概念和在Android應(yīng)用架構(gòu)中如何實(shí)現(xiàn)藍(lán)圖膝蜈。如果你沒有閱讀第一章節(jié)锅移,則這篇章節(jié)會(huì)有很多地方讓你不明白。所以饱搏,在你繼續(xù)閱讀前請先移步第一章節(jié)非剃。
我們將在第一章提到的藍(lán)圖為基礎(chǔ)上,用MVP架構(gòu)實(shí)現(xiàn)一個(gè)完整的Android應(yīng)用推沸。
這個(gè)項(xiàng)目的開發(fā)是為了提供適當(dāng)?shù)姆椒ㄈ?gòu)建一個(gè)Android APP备绽。它包含大多數(shù)情況下APP所有必須的代碼塊券坞。
這個(gè)項(xiàng)目一開始會(huì)讓你覺得非常復(fù)雜,但只要你花費(fèi)時(shí)間去探索疯坤,你將撥開它的迷霧报慕。這個(gè)項(xiàng)目以Dagger2,RxJava压怠,F(xiàn)astAndroidNetworking和PlaceHolderView 為基礎(chǔ)眠冈。
通過這個(gè)項(xiàng)目來學(xué)習(xí),研究它每一個(gè)代碼菌瘫,如果它們存在BUG或你能找到更加優(yōu)秀的邏輯實(shí)現(xiàn)蜗顽,請創(chuàng)建一個(gè)下拉請求。我們逐步地寫測試雨让,所以你空閑的時(shí)候也可以對(duì)其創(chuàng)建下拉請求來作貢獻(xiàn)雇盖。
這個(gè)APP有一個(gè)登陸頁和主頁。登錄頁實(shí)現(xiàn)私有賬號(hào)及谷歌和Facebook的第三登陸栖忠。第三方登錄使用虛假的api來實(shí)現(xiàn)崔挖。登陸功能基于獲取token,token用于后續(xù)訪問api庵寞。主界面創(chuàng)建了卡片狸相,有關(guān)于MVP的問題。這個(gè)庫包含的代碼是展示了作為骨架的絕大多數(shù)的應(yīng)用組件是如何工作捐川。
整個(gè)APP包結(jié)構(gòu)應(yīng)該分為五個(gè)部分:
data:包含所有數(shù)據(jù)獲取及他們的組件脓鹃。
di:依賴使用Dagger2提供的類。
ui:視圖類和與他們通訊的Presenter
service:應(yīng)用服務(wù)古沥。
utils:公共類瘸右。
類被設(shè)計(jì)成盡可能最大化被復(fù)用。
這有許多有趣的部分岩齿,如果我嘗試在開始就解釋他們會(huì)導(dǎo)致一次性引入太多概念太颤。所以我覺得最合適是對(duì)核心理念進(jìn)行解釋,讀者可以通過項(xiàng)目來掌握這樣的概念盹沈。我建議你在這個(gè)項(xiàng)目上至少花費(fèi)一周時(shí)間來進(jìn)行研究學(xué)習(xí)栋齿。
學(xué)習(xí) build.gradle 和查看所有在使用的依賴。
探索數(shù)據(jù)包和實(shí)現(xiàn)Helper類襟诸。
ui基礎(chǔ)包創(chuàng)建Activity Fragment SubView 和 Presenter的基本實(shí)現(xiàn)瓦堵。所有其他引用組件應(yīng)該被這個(gè)類派生出來。
di 包 應(yīng)用內(nèi)是提供依賴的類歌亲,明白依賴的注入菇用,通過Dagger2的說明來了解。
資源文件:styles,fonts,drawable.
通過第三篇文章掌握MVP在Dialogs,ViewPager,RecyclerView 和Adapters 的用法陷揪。
如果你的項(xiàng)目有很多開發(fā)人員同時(shí)工作和項(xiàng)目內(nèi)容非常巨大惋鸥,則閱讀這篇關(guān)于MVP延伸的文章杂穷。
非常高興我們在這一系列文章的第一第二章節(jié)中構(gòu)建起MVP架構(gòu)非常受歡迎,項(xiàng)目庫通過你的努力會(huì)更加完善卦绣。
在開發(fā)的過程中耐量,你在這個(gè)架構(gòu)中尋求很多關(guān)于基于View的實(shí)現(xiàn)的Dialog 和 Adapter。
在這個(gè)案例中滤港,你不用閱讀很早的資源廊蜒,我非常推薦這些在你讀這篇文章之前。這是他們的鏈接溅漾。
https://github.com/MindorksOpenSource/android-mvp-architecture
在這篇文章山叮,我們將對(duì)這個(gè)架構(gòu)的評(píng)級(jí)對(duì)話框和Activity進(jìn)行延伸。
首先列下所有特性和用例添履。
這個(gè)對(duì)話框會(huì)顯示五顆星來供用戶選擇他對(duì)APP的使用體驗(yàn)屁倔。
如果星星數(shù)量少于5,我們修改對(duì)話框暮胧,通過詢問改進(jìn)來反饋锐借。
如果星星數(shù)量等于5,我們顯示應(yīng)用商店排名選項(xiàng)來供用戶添加評(píng)論往衷。
排名信息將會(huì)發(fā)送到APP后端服務(wù)器钞翔。
這個(gè)評(píng)分對(duì)話框是用戶終端的非必須特性,但是對(duì)開發(fā)人員終端來說具有非常高價(jià)值炼绘。所以這款應(yīng)用必須非常巧妙地執(zhí)行這一功能。
我推薦使用大空間來間隔兩個(gè)連續(xù)的編程方式評(píng)分對(duì)話框的顯示妄田。