1. 程式人生 > >Android App整體架構設計的思考

Android App整體架構設計的思考

本文是對我在知乎一個回答的整理,其中的內容大多是對我平時的閱讀和實踐的總結,希望對Android的開發者有所幫助。但畢竟是個人的一些思考,難免有疏漏,也歡迎對本文的內容提出建議。

1. 架構設計的目的

        對程式進行架構設計的原因,歸根到底是為了提高生產力。通過設計使程式模組化,做到模組內部的高聚合和模組之間的低耦合。這樣做的好處是使得程式在開發的過程中,開發人員只需要專注於一點,提高程式開發的效率,並且更容易進行後續的測試以及定位問題。但設計不能違背目的,對於不同量級的工程,具體架構的實現方式必然是不同的,切忌犯為了設計而設計,為了架構而架構的毛病。舉個簡單的例子,一個Android App如果只有3個Java檔案,那隻需要做點模組和層次的劃分就可以,引入框架或者架構反而提高了工作量,降低了生產力。但我當前開發的App最終程式碼量應該在10W行以上,本地需要進行復雜操作,同時也需要考慮到與其餘的Android開發者以及後臺開發人員之間的同步配合,那就需要在架構上進行一些思考。

2. 基於MVP的架構設計思路

在App開發過程中,經常出現的問題就是某一部分的程式碼量過大,雖然做了模組劃分和介面隔離,但也很難完全避免。從實踐中看到,這更多的出現在UI部分,也就是Activity裡。我曾見過2000+行以上基本不帶註釋的Activity,那時我的第一反應就是想吐。Activity內容過多的原因其實很好解釋,因為Activity本身需要擔負與使用者之間的操作互動,再加上現在大部分的Activity還對整個App起到控制器的作用,這又帶入了大量的邏輯程式碼,造成Activity的臃腫。為了解決這個問題,我們引入了MVP框架思路。

2.1 什麼是MVP?

        MVP是一種使用廣泛的基礎架構模式,使用基於事件驅動的應用框架。MVP從更早的MVC框架演變過來的一種框架,與MVC有一定的相似性。MVP框架由3部分組成:View負責顯示,Presenter負責邏輯處理,Model提供資料。MVP與MVC之間最主要的區別在控制層上,在MVP框架中,View與Model並不直接互動,所有的互動放在Presenter中;而在MVC裡,View與Model會直接產生一定的互動。MVP的Presenter是框架的控制者,承擔了大量的邏輯操作,而MVC的Controller更多時候承擔一種轉發的作用。因此在App中引入MVP的原因,是為了將此前在Activty中包含的大量邏輯操作放到控制層中,避免Activity的臃腫。MVP的變種有很多,其中使用最廣泛的是Passive View模式,即被動檢視。在這種模式下,整個框架內部模組之間的邏輯操作均由Presenter控制,View僅僅是整個操作的彙報者和結果接收者,Model根據Presenter的單向呼叫返回資料(圖片來自網路)。並且MVP模式使得View與Model的耦合性更低,降低了Presenter對View的依賴,實現了關注點分離的初衷,方便開發人員的編碼和測試工作。

                                        

        具體到Android App中,我一般將App根據程式的結構進行縱向劃分,對應MVP分別為模型層,UI層和邏輯層。UI層一般包括Activity,Fragment,Adapter等直接和UI相關的類,UI層的Activity在啟動之後例項化相應的Presenter,App的控制權後移,由UI轉移到Presenter,兩者之間的通訊通過BroadCast、Handler或者介面完成,只傳遞事件和結果。舉個簡單的例子,UI層通知邏輯層(Presenter)使用者點選了一個Button,邏輯層(Presenter)自己決定應該用什麼行為進行響應,該找哪個模型(Model)去做這件事,最後邏輯層(Presenter)將完成的結果更新到UI層。

2.2 MVP架構存在的問題

        轉移邏輯操作之後可能部分較為複雜的Activity內程式碼量還是不少,於是在分層的基礎上再加入模板方法(Template Method)。具體做法是在Activity內部分層。其中最頂層為BaseActivity,不做具體顯示,而是提供一些基礎樣式,Dialog,ActionBar在內的內容,展現給使用者的Activity繼承BaseActivity,重寫BaseActivity預留的方法。如有必要再進行二次繼承,App中Activity之間的繼承次數最多不超過3次。

        模型層(Model)中的整體程式碼量是最大的,一般由大量的Package組成,針對這部分需要做的就是在程式設計的過程中,做好模組的劃分,進行介面隔離,在內部進行分層。

        強化Presenter的作用,將所有邏輯操作都放在Presenter內也容易造成Presenter內的程式碼量過大,對於這點,我的方法是在UI層和Presenter之間設定中介者Mediator,將例如資料校驗、組裝在內的輕量級邏輯操作放在Mediator中;在Presenter和Model之間使用代理Proxy;通過上述兩者分擔一部分Presenter的邏輯操作,但整體框架的控制權還是在Presenter手中。Mediator和Proxy不是必須的,只在Presenter負擔過大時才建議使用。最終的架構如下圖所示:

                                               

3 基於AOP的框架設計

        AOP(Aspect-Oriented Programming, 面向切面程式設計),誕生於上個世紀90年代,是對OOP(Object-Oriented Programming, 面向物件程式設計)的補充和完善。OOP引入封裝、繼承和多型性等概念來建立一種物件層次結構,用以模擬公共行為的一個集合。當我們需要為分散的物件引入公共行為的時候,OOP則顯得無能為力。也就是說,OOP允許你定義從上到下的關係,但並不適合定義從左到右的關係。例如日誌功能。日誌程式碼往往水平地散佈在所有物件層次中,而與它所散佈到的物件的核心功能毫無關係。對於其他型別的程式碼,如安全性、異常處理和透明的持續性也是如此。這種散佈在各處的無關的程式碼被稱為橫切(Cross-Cutting)程式碼,在OOP設計中,它導致了大量程式碼的重複,而不利於各個模組的重用。而AOP技術則恰恰相反,它利用一種稱為“橫切”的技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,並將其名為“Aspect”,即方面。所謂“方面”,簡單地說,就是將那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組間的耦合度,並有利於未來的可操作性和可維護性

                                                                  

3.1 AOP在Android中的使用

        AOP把軟體系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。在Android App中,哪些是我們需要的橫切關注點?個人認為主要包括以下幾個方面:Http, SharedPreferences, Json, Xml, File, Device, System, Log, 格式轉換等。Android App的需求差別很大,不同的需求橫切關注點必然是不一樣的。一般的App工程中應該有一個Util Package來存放相關的切面操作,在專案多了之後可以將其中使用較多的Util封裝為一個Jar包供工程呼叫。

4 總結

在使用MVP和AOP對App進行縱向和橫向的切割之後,能夠使得App整體的結構更清晰合理,避免區域性的程式碼臃腫,方便開發、測試以及後續的維護。目前很多尚停留在實踐和思想,今年上半年會抽時間寫一個基於MVP、AOP和IOC的Android框架。

5 快速開發框架

        目前網路上也有一些針對Android的快速開發框架,下面介紹3個主要的快速開發框架。針對這些快速開發框架,個人認為可以參考,但並不推薦使用,因為App整體依賴一個個人維護的框架風險實在太大,框架存在一些學習成本,本身也不一定完全符合App的需求,使用後的收益並沒有想象中大。

5.1 Afinal

        Afinal是一個Android的IOC,ORM框架,內建了四大模組功能:FinalAcitivity, FinalBitmap, FinalDb, FinalHttp。通過FinalActivity,可以通過註解的方式進行繫結UI和事件。通過FinalBitmap,可以方便的載入Bitmap圖片,而無需考慮OOM等問題。通過FinalDB模組,通過一行程式碼就可以對Android的SQlite資料庫進行增刪改查。通過FinalHttp模組,可以以Ajax形式請求Http資料。

GitHub專案地址:Afinal

5.2 xUtils

        xUtils目前主要包括4大模組:DbUtils, ViewUtils, HttpUtils, BitmapUtils。包含了很多實用的Android工具;支援大檔案上傳,更全面的Http請求協議支援,擁有更加靈活的ORM,更多的事件註解支援且不受混淆影響;最低相容Android 2.2 (Api Level 8)。

GitHub專案地址:xUtils

5.3 ThinkAndroid

ThinkAndroid是一個免費的開源的、簡易的、遵循Apache2開源協議釋出的Android開發框架,其開發宗旨是簡單、快速的進行 Android應用程式的開發,包含Android MVC、簡易SQlite ORM、IOC模組、封裝Android HttpClitent的Http模組, 具有快速構建檔案快取功能,無需考慮快取檔案的格式,都可以非常輕鬆的實現快取,它還基於檔案快取模組實現了圖片快取功能, 在Android中載入的圖片的時候,對OOM的問題,和對載入圖片錯位的問題都輕易解決。他還包括了一個手機開發中經常應用的實用工具類, 如日誌管理,配置檔案管理,Android下載器模組,網路切換檢測等等工具。

                   GOF等。