Plaid 是格子圖案的意思,也是一款在 2015 年開源的 Material Design 樣例應(yīng)用洲胖。它通過 API 調(diào)用聚合了 Dribbble济榨、Designer News 和 Product Hunt 三個網(wǎng)站的內(nèi)容數(shù)據(jù),并通過豐富的 UI 交互體驗呈現(xiàn)給用戶绿映。?
重構(gòu) Plaid 的目標(biāo)不僅是修復(fù)內(nèi)容源 API 接口的失效問題擒滑,更重要的是應(yīng)用最新的 Android Jetpack、Kotlin 語言特性和 Android 應(yīng)用架構(gòu)指南叉弦,因此 Plaid 2.0 將不僅僅是 Material Design 的示例應(yīng)用丐一,同時還將是一個使用了 Kotlin 的符合 Android 應(yīng)用架構(gòu)指南的示例應(yīng)用。?
本文將為大家分享和總結(jié) Android 團隊工程師們在重寫 Plaid 應(yīng)用時的實踐經(jīng)驗淹冰,前面部分將著重分享應(yīng)用的分層設(shè)計库车,后面部分是具體使用 Kotlin 實現(xiàn)的視頻,擴展閱讀部分提供了更多 Plaid 重構(gòu)以及 Kotlin 相關(guān)知識的文章樱拴。
Plaid 1.0
起初柠衍,我們定位 Plaid 將是一款 Material Design 樣例應(yīng)用,我們希望通過它展示 Material Design 的可以為交互體驗帶來的改進晶乔。
2017 年珍坊,這些內(nèi)容源的部分 API 發(fā)生了改動: Dribbble 的 Shots API 里不再返回評論的內(nèi)容,Shot 點贊和用戶關(guān)注的接口失效正罢。類似這樣的 API 改動阵漏,也同樣出現(xiàn)在了 Designer News 和 Product Hunt 這兩個內(nèi)容源。
不過腺怯,我們有失去也有得到: Kotlin 作為 Android 官方的首要支持編程語言這一重大的消息在 17 年 Google I/O 時公布袱饭。同年 11 月,Android Jetpack 系列內(nèi)的架構(gòu)組件 (Architecture Components) 1.0 版正式發(fā)布呛占,用以幫助開發(fā)者構(gòu)建高質(zhì)量的應(yīng)用虑乖,這份指南包含了移動應(yīng)用用戶體驗的說明,常見的架構(gòu)原則晾虑,推薦的應(yīng)用架構(gòu)說明和最佳實踐等疹味。
因此,在決定修復(fù) Plaid 應(yīng)用 Bug 的同時帜篇,我們希望為這個項目加入 Jetpack 架構(gòu)組件和引入 Kotlin 語言糙捺,使其成為一個更 "時尚" 的應(yīng)用。
重構(gòu) Plaid 應(yīng)用
Plaid 重構(gòu)的目標(biāo) / 要求有以下幾個:
? ?解決因內(nèi)容源的 API 失效而導(dǎo)致的功能缺失問題
? ?構(gòu)建模塊化笙隙、可擴展的應(yīng)用架構(gòu)洪灯,規(guī)范依賴引用和注入
? ?引入和使用 Kotlin 重構(gòu)現(xiàn)有功能
隨著 Android 平臺不斷的改進以及 Kotlin 在全球開發(fā)者社區(qū)的迅速流行,達到這個目標(biāo)變得更容易了竟痰。比如可以通過使用 Android App Bundles 動態(tài)增添新的新聞源签钩,使用新的 AndroidX 庫掏呼,使用 Jetpack,遵循 Android 應(yīng)用架構(gòu)指南構(gòu)建應(yīng)用等铅檩。
我們在應(yīng)用里使用了 Android App Bundles 的動態(tài)模塊功能為新的新聞源模塊接入提供可能憎夷。此外,我們?yōu)?Plaid 規(guī)劃了三層昧旨,分別是 Data 層拾给、Domain 層、UI 層兔沃,并設(shè)計了一些主要的類如下圖所示:
接下來我們一層一層的分享一些主要的類和它們的作用:
首先是 Data 層蒋得,這一層我們會關(guān)注數(shù)據(jù)的交互和持久化存儲,我們設(shè)計了 RemoteDataSource 和 LocalDataSource 兩個類乒疏,其中 RemoteDataSource 將用來與 API 服務(wù)交互窄锅,構(gòu)造請求數(shù)據(jù),接收響應(yīng)數(shù)據(jù)缰雇;而 LocalDataSource 則會負責(zé)將數(shù)據(jù)存儲在本地入偷,存儲的方式可以通過數(shù)據(jù)庫,或者 SharedPreferences械哟。
為了銜接和使用 RemoteDataSource 和 LocalDataSource 這兩個類疏之,我們設(shè)計了一個名為 Repository 的類,這個類將用于獲取和存儲數(shù)據(jù)暇咆,也可以把數(shù)據(jù)緩存到內(nèi)存里锋爪。
如果 Repository 類只依賴于一個數(shù)據(jù)源,每次都從后端獲取數(shù)據(jù)而不做任何臨時存儲的話爸业,在用戶離開當(dāng)前頁面重新返回時其骄,應(yīng)用將必須重新獲取數(shù)據(jù),即使數(shù)據(jù)未發(fā)生更改也是如此扯旷,這將會浪費寶貴的網(wǎng)絡(luò)帶寬拯爽,并且可能迫使用戶等待頁面完成加載。更多關(guān)于數(shù)據(jù)獲取的架構(gòu)設(shè)計和推薦钧忽,請參考《Jetpack 應(yīng)用架構(gòu)指南》毯炮。
實際的業(yè)務(wù)邏輯通常會比較復(fù)雜,我們設(shè)計了一些小型的輕量級并且可以復(fù)用的 UseCase 類耸黑,這些類將基于實際的業(yè)務(wù)邏輯來處理數(shù)據(jù)桃煎,由這些 UseCase 類構(gòu)成了應(yīng)用架構(gòu)的第二層: Domain 層。特別要提到的是大刊,每個 UseCase 類將只負責(zé)完成一個單獨的任務(wù)为迈,比如回復(fù)評論等:?
第三層是 UI 層,首先我們設(shè)計了一個 ViewModel 類,它的目標(biāo)將是為界面的顯示提供數(shù)據(jù)葫辐,以及根據(jù)用戶的操作觸發(fā)不同的響應(yīng)赋续,它的輸出是 LiveData:
在 UI 層使用 Activity 和 XML 顯示界面以及將用戶的操作轉(zhuǎn)發(fā)給 ViewModel。
LiveData 可以很好的跟 Activity 和 Fragment 配合使用另患,而且與 DataBinding 結(jié)合,可以直接將數(shù)據(jù)與 XML 綁定蛾绎,所以在 UI 層昆箕,這里我們選擇使用 LiveData 和 DataBinding。
使用 Kotlin (視頻)
Kotlin 語言有諸多特性 (如協(xié)程的 suspend 函數(shù)租冠、擴展函數(shù)和高階函數(shù)等) 可以幫助開發(fā)者更好的構(gòu)建應(yīng)用鹏倘。比如,我們在重構(gòu) Plaid 應(yīng)用時具體的利用擴展函數(shù)來提高 "when"?表達式的可讀性顽爹。請參考下面的視頻來了解更多有關(guān)的技巧和最佳實踐:
騰訊視頻鏈接
https://v.qq.com/x/page/q3006tgkwbk.html
Bilibili 視頻鏈接
https://www.bilibili.com/video/av70762038/
擴展閱讀
本文僅針對 Plaid 的應(yīng)用架構(gòu)和 Kotlin 實現(xiàn)進行了簡單描述,更多關(guān)于 Plaid 相關(guān)文章镜粤,包括 Android App Bundles捏题、AndroidX 重構(gòu),以及多模塊的依賴注入實踐等肉渴,請參看我們通過掘金翻譯計劃的社區(qū)內(nèi)容項目發(fā)布的文章:
Plaid 的 Android App Bundle 重構(gòu)實踐:
https://juejin.im/post/5c7fba65e51d45284d2f0107?
將 Plaid 遷移到 AndroidX :
https://juejin.im/post/5cb567cc6fb9a068a17c9728?
Plaid 應(yīng)用中使用 Dagger 管理依賴和在多模塊里的依賴注入 :
https://juejin.im/post/5cee7ae6f265da1b855c38db?
Plaid 2.0 應(yīng)用在 GitHub 開源公荧,查看更詳細的代碼實現(xiàn),或參與本開源項目同规,請查看:?https://github.com/android/plaid
關(guān)于 Kotlin 的更多知識循狰,可以參考我們之前發(fā)布的內(nèi)容《31 天,從淺到深輕松學(xué)習(xí) Kotlin》券勺,或?點擊這里?訪問 Android 開發(fā)者文檔網(wǎng)站绪钥。