
現(xiàn)在我們已經(jīng)確定模塊化是一個(gè)非常好的事情,模塊化應(yīng)用程序應(yīng)該如何?如何連接不同的模塊?這如何看待真正的應(yīng)用程序?
第二部分將探討一種簡單但非常有效的模塊化應(yīng)用程序方法。它將深入介紹不同類型的模塊,并展示這種方法的好處。
放棄
這絕不是模塊化應(yīng)用程序的唯一方法,但它確實(shí)提供了一些我們稍后會(huì)涉及的關(guān)鍵優(yōu)勢。
應(yīng)用結(jié)構(gòu)
讓我們從查看您正在處理的應(yīng)用程序開始:
- 它是否包含帶有多個(gè)標(biāo)簽/可點(diǎn)擊元素的主屏幕?
- 當(dāng)用戶點(diǎn)擊這些元素時(shí)會(huì)發(fā)生什么?
機(jī)會(huì)很高,將打開應(yīng)用程序的新全屏部分,通常由幾個(gè)子屏幕組成,以執(zhí)行特定操作。
比如看看gmail:
簡化后,它包含一個(gè)帶有應(yīng)用程序抽屜的主屏幕(收件箱),一個(gè)撰寫按鈕和收件箱中的電子郵件項(xiàng)目。單擊其中一個(gè)元素可引導(dǎo)您進(jìn)入新的全屏“功能”:
- 點(diǎn)擊電子郵件 - >閱讀電子郵件功能(一個(gè)屏幕)
- 點(diǎn)擊撰寫 - >編寫電子郵件功能(多個(gè)屏幕)
- 點(diǎn)擊設(shè)置(在抽屜里) - >設(shè)置(幾個(gè)屏幕)
高度簡化的應(yīng)用程序只是一個(gè)(全屏)屏幕的樹,其中多個(gè)屏幕通常形成用戶流。
讓我們調(diào)用所有這些“用戶流”功能。
現(xiàn)在讓我們考慮Android操作系統(tǒng)的設(shè)計(jì)方式:多個(gè)應(yīng)用程序可以通過意圖相互交互。這實(shí)際上非常酷,因?yàn)槿魏螒?yīng)用都可以請求執(zhí)行操作(例如拍照),而無需知道誰將處理該請求以及如何處理該請求。
Android系統(tǒng)只是通過隱式意圖系統(tǒng)將多個(gè)應(yīng)用程序鏈接在一起。
如果我們利用這些觀察結(jié)果并將我們的應(yīng)用程序分成幾個(gè)完全獨(dú)立的功能模塊,該怎么辦?使用簡單的“startActivityForResult”合約將每個(gè)功能分離的位置?
模塊化架構(gòu)
在將您的應(yīng)用分成多個(gè)功能時(shí),所有這些功能可能都取決于一些常見的業(yè)務(wù)邏輯或UI組件。因此,我們需要引入第三級“庫模塊”。
將所有這些結(jié)合在一起產(chǎn)生:

這種架構(gòu)基本上將應(yīng)用程序拆分為三個(gè)級別的模塊:
- App:鏈接功能模塊(通常只有一個(gè))
- 功能:自包含,全屏UI級別功能,包括Espresso測試。每個(gè)功能至少包含一個(gè)活動(dòng)和可選的導(dǎo)航圖。功能模塊永遠(yuǎn)不會(huì)直接相互依賴。
- 庫:跨多個(gè)功能共享的功能。不同的庫可以相互依賴
讓我們深入研究這三個(gè)層面。
功能模塊
可能最重要的模塊是功能模塊。它們具有以下特征:
- 一個(gè)android-library模塊
- 具有(可選)導(dǎo)航圖的單個(gè)活動(dòng)(
允許多個(gè)活動(dòng)) - 響應(yīng)隱式意圖并傳回結(jié)果
- 從不依賴于其他功能或應(yīng)用程序
- 依賴于幾個(gè)庫模塊
功能模塊與應(yīng)用中的全屏,連貫的面向用戶功能相對應(yīng):例如用戶登錄,應(yīng)用設(shè)置,圖片裁剪,......
導(dǎo)航
請注意,應(yīng)用程序中的導(dǎo)航被@emmaguy公開調(diào)查視為一項(xiàng)重大挑戰(zhàn)
第一個(gè)關(guān)鍵優(yōu)勢是功能模塊使應(yīng)用程序內(nèi)的導(dǎo)航變得更加容易。這是因?yàn)樗麄儗?dǎo)航問題分成了更小的部分:
- 功能中的導(dǎo)航 - >由功能本身處理
- 功能之間的導(dǎo)航 - >由app模塊處理
因此,不需要非常大而復(fù)雜的導(dǎo)航控制器!功能簡單地將應(yīng)用程序拆分為邏輯,連貫的流程。
更重要的是,導(dǎo)航組件為每個(gè)功能提供了其UI流的清晰可視化表示。這樣可以快速找出功能的作用。例如,游戲功能有什么作用?

最后不再猜測特定屏幕是如何命名的,只需跳轉(zhuǎn)到正確的功能,查找屏幕,您就可以找到片段/視圖,而無需猜測/記住他們的名字。
Scaling
其次,使這些獨(dú)立的功能完全脫離其實(shí)現(xiàn)。因此通過設(shè)計(jì)消除不同功能團(tuán)隊(duì)之間的合并沖突!
嘗試新技術(shù)也變得更加容易:您可以輕松地從單一功能中的新技術(shù)端到端獲益。評估它是否對您的團(tuán)隊(duì)有益,如果選擇不當(dāng),所有效果都包含在一個(gè)模塊中!
如果您決定啟動(dòng)第二個(gè)應(yīng)用程序(或SDK),您可以在新的應(yīng)用程序模塊中將現(xiàn)有功能與新功能一起打包。
測試
由于所有功能都可以使用意圖直接啟動(dòng),因此Espresso無需單步執(zhí)行應(yīng)用程序的其他部分即可獲得要測試的功能。
這不僅使測試更簡單,更快速,而且更少的步驟也使它們更可靠,并且測試不再因其他功能中的錯(cuò)誤而中斷!
圖書館模塊
庫提供共享管道,可在多個(gè)或所有功能中重復(fù)使用。他們的特點(diǎn)是:
- android庫,純Java或純Kotlin模塊
- 從不依賴于功能或應(yīng)用程序
- 可以(但不必)依賴于其他庫
因此,庫可以非常多樣化:例如UI組件,數(shù)據(jù)存儲,網(wǎng)絡(luò)通信,標(biāo)準(zhǔn)庫,...
如果功能是應(yīng)用程序的“垂直切片”,則庫是“水平切片”,為其他幾個(gè)模塊提供功能。
應(yīng)用模塊
為了將應(yīng)用程序發(fā)送給用戶,必須將所有功能鏈接在一起:app模塊。
在這樣做時(shí),app模塊在功能之間協(xié)調(diào)導(dǎo)航。它使用功能切換來確定應(yīng)該啟用什么和不啟用什么。
這些功能切換非常強(qiáng)大,因?yàn)橥ㄟ^在一個(gè)應(yīng)用程序中運(yùn)送同一功能的多個(gè)版本(例如舊版和重寫版),應(yīng)用程序模塊允許逐步將重寫的功能推廣給用戶。
if (isRewriteFeatureEnabled) {
startActivityForResult(Intent("rewritten_feature"))
} else {
startActivityForResult(Intent("feature"))
}
最后,啟動(dòng)多個(gè)應(yīng)用程序并在它們之間共享功能就像創(chuàng)建新的應(yīng)用程序模塊一樣簡單。
包起來
重新安裝,這個(gè)簡單的三層應(yīng)用程序,功能和庫架構(gòu)具有以下優(yōu)點(diǎn):
- 通過拆分功能內(nèi)和跨功能導(dǎo)航來簡化導(dǎo)航
- 可以輕松找到屏幕并了解功能(特別是在使用導(dǎo)航圖時(shí))
- 支持?jǐn)U展團(tuán)隊(duì):功能團(tuán)隊(duì)之間的合并沖突更少,因?yàn)楣δ芤呀怦?/li>
- 使測試自動(dòng)化更容易:功能可以直接啟動(dòng),無需首先通過應(yīng)用程序到該功能
- 簡化了新技術(shù)的實(shí)驗(yàn):快速實(shí)現(xiàn)功能內(nèi)的端到端優(yōu)勢+不良技術(shù)選擇的低成本(與應(yīng)用程序的其他部分隔離)
-
允許使用功能切換分階段推出重寫功能
image


