Android架構:第一部分-每一個新的開始都很艱難 (譯)

本系列文章的目標是概述咱們與Android應用程序體系結構(Android體系結構)的鬥爭。 我意識到,不管Android應用程序架構的實施可能會如此痛苦,事實證實,這是我一直在努力的每個優秀應用程序的基礎。android

每項技術都有其天然演變。 或者更準確地說,它的社區經歷了進化過程。 早期採用新計算機語言或框架的用戶只是但願掌握技術並儘快完成一些工做。 一般狀況下,新社區很小,開發人員之間知識轉移的潛力有限,也就是說,因爲沒有可用的架構指導原則,每一個人都從本身的錯誤中學習。數據庫

Android architecture part 1

早期的Android並不例外。 這對開發人員來講既酷又有吸引力,它爲早期採用者成爲圍繞這一快速發展技術的社區的一部分提供了機會。編程

早期Android時代的痛點:谷歌是否關心?

你能夠爭辯說,那裏有許多資深人士,他們擁有不少不一樣技術的經驗,而且很快就會提出標準。 嗯,不必定。 若是這個技術背後有一個強大的公司能夠賺錢,他們確定會有本身的技術傳播者,他們會傳播關於這種新語言如何酷的文字,而且能夠用它作不少事情,這很容易學習,擴展並知足數百萬客戶的需求。架構

微軟常常用它的技術作到這一點。 另外一方面,當谷歌購買Android時,我誠實地認爲他們將其視爲一些其餘方面的項目。 若是您從一開始就一直處於Android世界,那麼您必須記住Google根本不關心您的挫折感和感覺。 那些擁有更多經驗,能力和幫助社區的意願的傢伙如今已經成爲Android超級巨星或者小半神 - 例如Jake Wharton。app

「When Google bought Android, I honestly think they treated it just as some other side project.」框架

xamvxi

你能夠說的另外一件事是你沒必要考慮不少關於代碼的架構和組織,由於框架爲你作了。 Android強制你將你的屏幕顯示放入Activities中,將可重複使用的屏幕材料分解成Fragments,並將後臺的東西放入Services中,並使用Broadcast Receivers與其餘人交談,所以它使您的生活變得更加美好。 對? 沒有dom

首先,無論技術如何,都有一些很好的作法和原則。 例如單一責任原則或依賴倒置原則,面向接口編程,殺死全局狀態,試圖謀殺全部狀態等等。ide

框架不多迫使你遵循原則。 相反,他們以最糟糕的方式違反了原則。 想一想Context,你必須在任何地方使用的上帝對象,各類單例,Fragments的生命週期(那是噩夢般的生活),AsyncTasks一般被錯誤地實現,因此他們吸食記憶,食物,水 ,並從您的APP中散發出來。單元測試

對於沒有指南的年輕開發人員來講,製造怪物比製造APP簡單。 把它想象成一個意大利麪般黑洞般的怪物-它做爲一個Pastafarian神只是一個很好的選擇,但做爲APP並很差。學習

android architecture spagetti monster

最後,技術和框架隱藏了APP的目的。 好的,這是一個Android應用程序,可是什麼樣的Android應用程序? 新聞閱讀器? 音樂播放器? 語言學習應用程序? 天氣應用? 也許這是另外一個待辦事項清單應用程序。 若是全部的東西都捆綁在框架提供的類中,那麼你會說不清楚。

正如Robert Martin, aka Uncle Bob所說:「Your architecture should scream the purpose of the app.」更技術性地說,業務邏輯應該明確分開,而且獨立於框架。

Android架構的四大黃金規則(或任何架構)

我但願如今很清楚,您不能依賴框架來使您的代碼整齊有序,特別是在Android裏。 在FIve裏,咱們很早就意識到這一點,但缺少當即提出核心的經驗。 失敗真正顯示出來須要很長時間,而且在項目中間沒法更改整個架構。 你也沒法花時間將舊項目重構爲新的酷炫的求之不得的最佳架構。 因此,咱們採起了漸進式的方法,逐漸從項目到項目逐步構建咱們的架構,並從錯誤中學習。 咱們認爲咱們的架構應該知足幾個目標,咱們能夠將咱們的方法與這些目標進行比較。 良好的架構應該作到如下幾點:

  1. Satisfy a multitude of stakeholders.(知足各方利益者)
  2. Encourage separation of concerns.(鼓勵的關注點分離)
  3. Run away from the real world (Android, DB, Internet…).
  4. Enable your components to be testable.(使您的組件成爲可測試的)

I. Satisfy a multitude of stakeholders.(知足各方利益者)

Stakeholder(在這篇文章中)是任何對你的APP感興趣的人。 除開發者外,還有UI設計師,UX設計師,PM,DB管理員,QA等。

固然,你不能以某種方式組織代碼,例如,UX設計人員能夠當即打開項目並理解全部內容,甚至能夠進行一些更改。 這是一個獨角獸。

Android Architecture stakeholders

個人意思是,你能夠組織你的代碼,使得當前與UX設計師一塊兒工做的開發人員只能管理與UX相關的東西。 因此,全部的交互都在classes / modules / components /中分開,就算他們的工做是交互做用。並且特定的開發人員只在應用的UX部分工做時在這些組件上工做。

II. Encourage separation of concerns.(鼓勵的關注點分離)

我以前所說的是一個關注點分離的例子。 咱們鼓勵這種特殊的方法,由於它能夠很好地映射到團隊和項目階段的組織,可是您的架構也應該鼓勵常規分離關注點。 分離問題或單一職責原則說,每一個組件都應該只有一個理由須要改變。

III. Run away from the real world (Android, DB, Internet…).

從現實世界中逃脫出來的這個特殊點已經在以前提到過了。 咱們已經說過,咱們想要表現APP真正的功能而已。 咱們想要強調業務邏輯,並在框架下留下框架細節。 這一點應該更增強烈:咱們不只要隱藏框架細節,還要隱藏與外部世界相關的全部細節。

Android Architecture under the hood

基本全部的Android的東西如傳感器,通知機制,屏幕細節,數據庫訪問,Internet訪問等等都是nitty gritty dirty

IV. Enable your components to be testable.

您應該儘量單元測試您的APP,而且您的架構應該容許您執行此操做。 若是你不能單元測試一切,你至少應該用測試來覆蓋你的業務邏輯。 與現實世界的分離與此相得益彰。 若是它明顯與應用程序的其餘部分分離,則測試業務邏輯會更容易。

giphy-5

第一次迭代 - 上帝的活動

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public final class UsersActivity extends ListActivity {

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       //...

       new ListUsers().execute();

   }

   private final class ListUsers extends AsyncTask<Void, Void, Void> {

       @Override

       protected Void doInBackground(Void... voids) {

           // final SQLiteOpenHelper sqLiteOpenHelper = ...

           // JsonObjectRequest jsObjRequest = new JsonObjectRequest

           // (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

           // MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

           // showData(user);

           return null;

       }

   }

}

你可能在「古代時代」看到過相似的代碼。若是你尚未,那麼你還很年輕。 這有什麼問題? Everything!

no

咱們有一個涉及數據庫,進入互聯網,解析,產生線程和呈現數據的Activity。 因此,全部的利益相關者都在關注單個類,沒有任何問題是分離的,它不是可測試的,業務邏輯與Android的東西混雜在一塊兒。

android architecture part 1 - 1

##第二次迭代 - MVP

第一種方法顯然不起做用。 咱們嘗試的第一件事情之一是MVP,或model-view-presenter。 每一個人都熟悉MVP。 它是最受歡迎的架構之一。 它看起來像這樣:

android architecture part 2 - 2

在這裏,咱們分離了其實是咱們的Android Fragments的視圖,咱們有表明咱們業務的(domain)模型,最後咱們有協調全部這些的presenters。 確定會更好。 關注點有些分離,利益相關者再也不困惑,你能夠寫一些測試。 然而,咱們仍然與現實世界混淆,由於presenter直接觸及數據庫和全部內容。 這是一個神的對象。 它處理模型,它將數據發送到視圖,它擁有業務邏輯(業務邏輯是那些齒輪:)),而且它傳遞到數據庫和Internet,獲取傳感器數據等等。因此,更好,可是 它能夠變得更好。

android architecture part 1 - 3

第三次迭代 - MVP + managers

當政府不知道該作什麼時,他們作了什麼? 它設置一個機構。 當開發者不知道該怎麼作時,他們會作什麼? 他們採用一些managers。 您沒必要將其命名爲「manager」。這些類有不少名稱:utils,helper,fooBarBuzz-ator等等。咱們統稱爲managers。

android architecture part 1 - 4

說實話,這甚至有點奏效。 業務邏輯包含在manager類中。 利益相關者知道在哪裏看,關注是分開的,但他們可能更多,你能夠編寫更多的測試,但你仍然直接觸摸Android,因此你必須編寫Android測試用例和預填充數據庫來測試業務邏輯,這很慢。 是的,managers每每是巨大的野獸,很快就很難維持。 你能夠爭辯說,它不須要比如今更復雜,你能夠經過使用更簡單的架構來更快地傳遞代碼,可是這種方法會出現更多的錯誤,而且可維護性會受到影響。

android architecture part 1 - 5

總結

在本系列的第一部分中,咱們遇到了建立實際可行的Android體系結構的挑戰。 良好的Android架構應該知足衆多利益相關者的需求,鼓勵分離問題,強調業務邏輯,並將框架細節置於隱患之下,並使全部組件均可測試。 在系列的第二部分中,咱們將向您展現咱們如何管理那些對咱們有用的東西。 在此以前,您對如何建立適當的Android工做流程有任何建議嗎? 你遇到了什麼問題?

Continue to part 2.

您還能夠查看其餘部分:

Part 5: How to Test Clean Architecture

Part 4: Applying Clean Architecture on Android (Hands-on)

Part 3: Applying Clean Architecture on Android

相關文章
相關標籤/搜索