自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

最實(shí)用的Android架構(gòu)設(shè)計(jì)原則

移動(dòng)開(kāi)發(fā) Android
照這么一說(shuō),軟件是隨著時(shí)間發(fā)展和改變的,是架構(gòu)上的發(fā)展和改變。實(shí)際上,好的軟件設(shè)計(jì)必須能夠幫助我們發(fā)展和擴(kuò)充解決方案,保持其健壯性,而不 必每件事都重寫代碼(雖然在某些情況下重寫的方法更好,但是那是另一篇文章的話題,所以相信我,讓我們聚焦在前面所討論的話題上)。

開(kāi)始之前,假設(shè)你已經(jīng)閱讀過(guò)我之前撰寫的文章“ Architecting Android…The clean way ?”。如果還沒(méi)有閱讀過(guò),為了更好地理解這篇文章,應(yīng)借此機(jī)會(huì)讀一讀:


架構(gòu)演變

演變意味著一個(gè)循序漸進(jìn)的過(guò)程,由某些狀態(tài)改變到另一種不同的狀態(tài),且新?tīng)顟B(tài)通常更好或更復(fù)雜。

照這么一說(shuō),軟件是隨著時(shí)間發(fā)展和改變的,是架構(gòu)上的發(fā)展和改變。實(shí)際上,好的軟件設(shè)計(jì)必須能夠幫助我們發(fā)展和擴(kuò)充解決方案,保持其健壯性,而不 必每件事都重寫代碼(雖然在某些情況下重寫的方法更好,但是那是另一篇文章的話題,所以相信我,讓我們聚焦在前面所討論的話題上)。

在這篇文章中,我將講解我認(rèn)為是必需的和重要的要點(diǎn),為了保持基本代碼條理清晰,要記住下面這張圖片,我們開(kāi)始吧!


響應(yīng)式方法:RxJava

因?yàn)橐呀?jīng) 有很多這方面的文章 ,還有這方面 做得很好、令人景仰的人 ,所以我不打算在這里討論RxJava的好處( 我假設(shè)您已經(jīng)對(duì)它有所體驗(yàn)了 )。但是,我將指出在Android應(yīng)用程序開(kāi)發(fā)方面的有趣之處,以及如何幫助我形成***個(gè)清晰的架構(gòu)的方法。

首先,我選擇了一種響應(yīng)式的模式通過(guò)轉(zhuǎn)換usecase(在這個(gè)清晰的架構(gòu)命名規(guī)則中,其被稱為interactor)返回Observables<T>,表示所有底層都遵循這一鏈條,也返回Observables<T> 。

實(shí)戰(zhàn)解析Android架構(gòu)設(shè)計(jì)原則

正如你所看到的,所有用例繼承這個(gè)抽象類,并實(shí)現(xiàn)抽象方法buildUseCaseObservable()。該方法將建立一個(gè)Observables<T>,它承擔(dān)了繁重的工作,還要返回所需的數(shù)據(jù)。

需要強(qiáng)調(diào)是,在execute()方法中,要確保Observables<T> 是在獨(dú)立線程執(zhí)行,因此,要盡可能減輕阻止android主線程的程度。其結(jié)果就是會(huì)通過(guò)android主線程調(diào)度程序?qū)⒅骶€程壓入線程隊(duì)列的尾部(push back)。

到目前為止,我們的Observables<T>啟動(dòng)并且運(yùn)行了。但是,正如你所知,必須要觀察它所發(fā)出的數(shù)據(jù)序列。要做到這一點(diǎn), 我改進(jìn)了presenters(MVP模式表現(xiàn)層的一部分),把它變成了觀察者(Subscribers),它通過(guò)用例對(duì)發(fā)出的項(xiàng)目做出“react”, 以便更新用戶界面。

觀察者是這樣的:

實(shí)戰(zhàn)解析Android架構(gòu)設(shè)計(jì)原則

每個(gè)觀察者都是每個(gè)presenter的內(nèi)部類,并實(shí)現(xiàn)了一個(gè)Defaultsubscriber<T>接口,創(chuàng)建了基本的默認(rèn)錯(cuò)誤處理。

將所有的片段放在一起后,通過(guò)下面的圖,你可以獲得完整的概念:

 

讓我們列舉一些擺脫基于RxJava方法的好處:

在觀察者(Subscribers)與被觀察者(Observables)之間去耦合:更加易于維護(hù)和測(cè)試。

簡(jiǎn)化異步任務(wù):如果要求多個(gè)異步執(zhí)行時(shí),如果需要一個(gè)以上異步執(zhí)行的級(jí)別,Java的thread和future的操作和同步比較復(fù)雜,因此 通過(guò)使用調(diào)度程序,我們可以很方便地(不需要額外工作)在后臺(tái)與主線程之間跳轉(zhuǎn),特別是當(dāng)我們需要更新UI時(shí)。還可以避免“回調(diào)的坑”—— 它使我們代碼可讀性差,且難以跟進(jìn)。
數(shù)據(jù)轉(zhuǎn)換/組成:在不影響客戶端情況下,我們能夠整合多個(gè)Observables<T>,使解決方案更靈活。
錯(cuò)誤處理:在任何Observables<T>內(nèi)發(fā)生錯(cuò)誤時(shí),就向消費(fèi)者發(fā)出信號(hào)。

從我的角度看有一點(diǎn)不足,甚至要為此需要付出代價(jià),那些還不熟悉概念的開(kāi)發(fā)人員還是要遵循學(xué)習(xí)曲線。但你從中得到了極有價(jià)值的東西。為了成功而reactive起來(lái)吧!
依賴注入:Dagger 2

關(guān)于依賴注入, 因?yàn)槲乙呀?jīng)寫了一篇完整的文章 ,我不想說(shuō)太多。強(qiáng)烈建議你閱讀它,這樣我們就可以接著說(shuō)下面的內(nèi)容了。

值得一提的是,通過(guò)實(shí)現(xiàn)一個(gè)像Dagger 2那樣的依賴注入框架我們能夠獲得:

組件重用,因?yàn)橐蕾嚨膶?duì)象可以在外部注入和配置。
當(dāng)注入對(duì)象作為協(xié)作者(collaborators)時(shí),由于對(duì)象的實(shí)例存在于在一個(gè)隔離和解耦地方,這樣在我們的代碼庫(kù)中,就不需要做很多的改變,就可以改變?nèi)魏螌?duì)象的實(shí)現(xiàn)。
依賴可以注入到一個(gè)組件:這些將這些模擬實(shí)現(xiàn)的依賴對(duì)象注入成為可能,這使得測(cè)試更容易。

Lambda表達(dá)式:Retrolambda

沒(méi)有人會(huì)抱怨在代碼中使用Java 8的lambada表達(dá)式,甚至在簡(jiǎn)化并擺脫了很多樣板代碼以后,使用得更多,如你看到這段代碼:

 

實(shí)戰(zhàn)解析Android架構(gòu)設(shè)計(jì)原則

然而,我百感交集,為什么呢?我們?cè)?@SoundCloud 討論 Retrolambada ,主要是是否使用它,結(jié)果是:

1. 贊成的理由:

Lambda表達(dá)式和方法引用
“try-with-resources”語(yǔ)句
使用karma做開(kāi)發(fā)

2. 反對(duì)的理由:

Java 8 API的意外使用
十分令人反感的第三方庫(kù)
要與Android一起使用的第三方插件Gradle

***,我們認(rèn)定它不能為我們解決任何問(wèn)題:你的代碼看起來(lái)很好且具有可讀性,但這不是我們與之共存的東西,由于現(xiàn)在所有功能***大的IDE都包含代碼折疊式選項(xiàng),這就涵蓋這一需求了,至少是一個(gè)可接受的方式。

說(shuō)實(shí)話,盡管我可能會(huì)在業(yè)余時(shí)間的項(xiàng)目中使用它,但在這里使用它的主要原因是嘗試和體驗(yàn)Android中Lambda表達(dá)式。是否使用它由你自己決定。在這里我只是展示我的視野。當(dāng)然,對(duì)于這樣一個(gè)了不起的工作,這個(gè) 庫(kù) 的作者值得我的稱贊。
測(cè)試方法

在測(cè)試方面,與示例的***個(gè)版本相關(guān)的部分變化不大:

表現(xiàn)層:用Espresso 2和Android Instrumentation測(cè)試框架測(cè)試UI。
領(lǐng)域?qū)樱篔Unit + Mockito —— 它是Java的標(biāo)準(zhǔn)模塊。
數(shù)據(jù)層:將測(cè)試組合換成了Robolectric 3 + JUnit + Mockito。這一層的測(cè)試曾經(jīng)存在于單獨(dú)的Android模塊。由于當(dāng)時(shí)(當(dāng)前示例程序的***個(gè)版本)沒(méi)有內(nèi)置單元測(cè)試的支持,也沒(méi)有建立像 robolectric那樣的框架,該框架比較復(fù)雜,需要一群黑客的幫忙才能讓其正常工作。

幸運(yùn)的是,這都是過(guò)去的一部分,而現(xiàn)在所有都是即刻可用,這樣我可以把它們重新放到數(shù)據(jù)模塊內(nèi),專門為其默認(rèn)的測(cè)試路徑:src/test/java。
包的組織

我認(rèn)為一個(gè)好的架構(gòu)關(guān)鍵因素之一是代碼/包的組織:程序員瀏覽源代碼遇到的***件事情就是包結(jié)構(gòu)。一切從它流出,一切依賴于它。

我們能夠辨別出將應(yīng)用程序封裝進(jìn)入包(package)的2個(gè)路徑:

按層分包:每一個(gè)包(package)中包含的項(xiàng)通常不是彼此密切相關(guān)的。這樣包的內(nèi)聚性低、模塊化程度低,包之間偶合度高。因此,編輯某個(gè)特性要編輯來(lái)自不同包的文件。另外,單次操作幾乎不可能刪除掉某個(gè)功能特性。
按特性分包:用包來(lái)體現(xiàn)特性集。把所有相關(guān)某一特性(且僅特性相關(guān))的項(xiàng)放入一個(gè)包中。這樣包的內(nèi)聚性高,模塊化程度高,包之間偶合度低。緊密相關(guān)的項(xiàng)放在一起。它們沒(méi)有分散到整個(gè)應(yīng)用程序中。

我的建議是去掉按特性分包,會(huì)帶來(lái)的好處有以下主要幾點(diǎn):

模塊化程度更高
代碼導(dǎo)航更容易
功能特性的作用域范圍最小化了

如果與功能特性團(tuán)隊(duì)一起工作(就像我們?cè)贎SoundCloud的所作所為),也會(huì)是非常有趣的事情。代碼的所有權(quán)會(huì)更容易組織,也更容易被模塊化。在許多開(kāi)發(fā)人員共用一個(gè)代碼庫(kù)的成長(zhǎng)型組織當(dāng)中,這是一種成功。

如你所見(jiàn),我的方法看起來(lái)就像按層分包:這里我可能會(huì)犯錯(cuò)(例如,在“users”下組織一切),但在這種情況下我會(huì)原諒自己,因?yàn)檫@是個(gè)以學(xué)習(xí)為目的的例子,而且我想顯示的是清晰架構(gòu)方法的主要概念。領(lǐng)會(huì)其意,切勿盲目模仿:-)。
還需要做的事:組織構(gòu)建邏輯

我們都知道,房子是從地基上建立起來(lái)的。軟件開(kāi)發(fā)也是這樣,我想說(shuō)的是,從我的角度來(lái)看,構(gòu)建系統(tǒng)(及其組織)是軟件架構(gòu)的重要部分。

在Android平臺(tái)上,我們采用Gradle,它事實(shí)上是一種與平臺(tái)無(wú)關(guān)的構(gòu)建系統(tǒng),功能非常強(qiáng)大。這里的想法是通過(guò)一些提示和技巧,讓你組織構(gòu)建應(yīng)用程序時(shí)能夠得到簡(jiǎn)化。

在單獨(dú)的gradle構(gòu)建文件中按功能對(duì)內(nèi)容進(jìn)行分組

 

 

因此,你可以用“apply from: ‘buildsystem/ci.gradle’”插入到任何Gradle建立的文件中進(jìn)行配置。不要把所有都放置在一個(gè)build.gradle文件中,否則就是去創(chuàng)建一個(gè)怪物,這是教訓(xùn)。

創(chuàng)建依賴關(guān)系圖

實(shí)戰(zhàn)解析Android架構(gòu)設(shè)計(jì)原則

如果想在項(xiàng)目的不同模塊間重用相同的組件版本,這很好;否則就要在不同的模塊間使用不同的版本的組件依賴。另外一點(diǎn),你是在同一個(gè)地方控制依賴關(guān)系,像組件版本發(fā)生沖突這樣的事情一眼就能看出來(lái)。
結(jié)語(yǔ)

到目前為止講了那么多,一句話,要記住沒(méi)有靈丹妙藥。但好的軟件架構(gòu)會(huì)幫助代碼保持清晰和健壯,還可以保持代碼的可擴(kuò)展性,易于維護(hù)。

我想指出一些事情。面對(duì)軟件存在的問(wèn)題,要報(bào)以本應(yīng)當(dāng)解決的態(tài)度:

遵守SOLID原則
不要過(guò)度思考(不過(guò)度工程化)
務(wù)實(shí)

盡可能降低(Android)框架中模塊的依賴性
 

責(zé)任編輯:chenqingxiang 來(lái)源: 隨時(shí)隨地學(xué)Java
相關(guān)推薦

2021-05-07 15:27:23

架構(gòu)設(shè)計(jì)架構(gòu)開(kāi)發(fā)

2023-07-09 15:24:05

架構(gòu)設(shè)計(jì)思想AKF

2021-11-01 21:01:01

架構(gòu)設(shè)計(jì)軟件

2013-09-02 17:46:41

MVC架構(gòu)設(shè)計(jì)MVC架構(gòu)設(shè)計(jì)

2023-05-12 07:52:13

架構(gòu)設(shè)計(jì)設(shè)計(jì)原則

2024-08-16 14:01:00

2024-09-09 09:00:12

架構(gòu)設(shè)計(jì)算法

2025-01-15 08:10:29

Java架構(gòu)代碼

2024-09-19 08:46:46

SPIAPI接口

2023-07-17 15:09:08

SaaS架構(gòu)平臺(tái)

2025-04-15 04:00:00

2013-09-02 17:53:41

MVC架構(gòu)設(shè)計(jì)MEF

2022-12-30 08:16:34

2020-08-27 14:22:29

MySQL數(shù)據(jù)庫(kù)架構(gòu)設(shè)計(jì)

2009-05-05 10:24:48

應(yīng)用架構(gòu)設(shè)計(jì)原則

2013-05-27 10:58:28

Tumblr架構(gòu)設(shè)計(jì)雅虎收購(gòu)

2023-05-12 08:06:46

Kubernetes多云架構(gòu)

2022-02-25 15:56:44

云計(jì)算架構(gòu)基礎(chǔ)設(shè)施

2015-06-02 04:17:44

架構(gòu)設(shè)計(jì)審架構(gòu)設(shè)計(jì)說(shuō)明書

2009-07-06 10:36:41

敏捷開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)