Facebook移動架構:Android Flux架構詳解

要為Android應用找到一個好的架構不是一件容易的事情。谷歌似乎不太在乎這個事情,因此在設計模式上表箭,除了Activity生命周期管理之外,再也沒有官方的推薦钮莲。

但是免钻,為你的應用打造一個架構是非常重要的。不管你是否喜歡崔拥,任何應用最終都會有一個架構极舔。因此你最好是成為一個架構的奠基人,而不是等著它出現(xiàn)链瓦。

今天:Clean Architecture

目前的趨勢是采用Uncle Bob在2012年對web應用提出的建議:Clean Architecture.

但是我發(fā)現(xiàn)Clean Architecture對于絕大多數(shù)安卓應用來說都有點過度設計了拆魏。

通常移動應用要比web應用的生命短。移動端技術的發(fā)展太快慈俯,以至于今天發(fā)行的app可能在一年后已經完全過時渤刃。

移動應用所做的事情很少。絕大多數(shù)的用例都只是數(shù)據(jù)信息流的消費贴膘。從API獲取數(shù)據(jù)卖子,顯示數(shù)據(jù)給用戶,很少有輸入與寫入刑峡。

所以它的業(yè)務邏輯并不復雜洋闽。至少不如后端一樣的復雜玄柠。雖然你要處理很多平臺上的問題:內存,存儲诫舅,暫停羽利,恢復,網絡骚勘,定位等等铐伴,但是這些都不是業(yè)務邏輯。所有app都有這些東西俏讹。

因此当宴,絕大多數(shù)app似乎都無法從類似于復雜的分層或者工作執(zhí)行優(yōu)先級隊列中獲益。

他們也許只是需要一種組織代碼的簡單方式泽疆,能高效的一起工作户矢,更容易的發(fā)現(xiàn)bug

Flux架構介紹

Flux架構被Facebook使用來構建他們的客戶端web應用。跟Clean Architecture一樣殉疼,它不是為移動應用設計的梯浪,但是它的特性和簡單可以讓我們很好的在安卓項目中采用。

要理解Flux,有兩個關鍵的特點

1.數(shù)據(jù)流總是單向的瓢娜,一個單向的數(shù)據(jù)流是Flux架構的核心挂洛,也是它簡單易學的原因。就如下面討論的眠砾,在進行應用測試的時候虏劲,它提供了非常大的幫助。

2.應用被分成三個主要部分:

(1)View:應用的界面褒颈。這里創(chuàng)建響應用戶操作的action柒巫。

(2)Dispatcher:中心樞紐,傳遞所有的action,負責把它們運達每個store谷丸。

(3)Store:維護一個特定application domain的狀態(tài)堡掏。它們根據(jù)當前狀態(tài)響應action,執(zhí)行業(yè)務邏輯,同時在完成的時候發(fā)出一個change事件刨疼。這個事件用于view更新其界面

這三個部分都是通過Action來通信的:一個簡單的基本對象泉唁,以類型來區(qū)分,包含了和操作相關的數(shù)據(jù)揩慕。

Flux Android架構

在Android開發(fā)中使用Flux設計規(guī)范的目的是建立一個在簡單性與易擴展易測試之間都比較平衡的架構游两。

第一步是找到Flux元素和安卓app組件之間的映射。

其中兩個元素非常容易找到與實現(xiàn)漩绵。

(1)View:Activity或者Fragment

(2)Dispatcher:一個事件總線(event bus)贱案,在我的例子中將使用Otto,但是其它任何實現(xiàn)都應該是OK的。

Actions

Actions也不復雜宝踪。它們的實現(xiàn)和POJO一樣簡單侨糟,有兩個主要屬性:

(1)Type:一個String,定義了事件的類型。

(2)Data:一個map,裝載了本次操作

比如瘩燥,一個顯示用戶詳情的典型action如下:

Bundle data = new Bundle();

data.put("USER_ID",id);

Action action = new ViewAction("SHOW_USER",data);

Stores

這可能是Flux理論中最難的部分秕重。

如果你之前使用過Clean Architecture,你可能難以接受。因為Stores承擔了原本被分成多層的責任Stores包含了application的狀態(tài)與它的業(yè)務邏輯厉膀。它們類似于rich data models但是可以管理多個對象的狀態(tài)溶耘,而不僅僅是一個對象。

Stores響應Dispatcher發(fā)出的Action,執(zhí)行業(yè)務邏輯并發(fā)送change事件服鹅。

Stores的唯一輸出是這單一的事件:change凳兵。其它對Store內部狀態(tài)感興趣的組件必須監(jiān)聽這個事件,同時使用它獲取需要的數(shù)據(jù)企软。

系統(tǒng)中不再需要任何其它組建了解application的任何狀態(tài)信息庐扫。

最后,stores必須對外公開一個獲取application狀態(tài)的接口仗哨。這樣形庭,view元素可以查詢Stores然后相應的更新UI。

比如厌漂,在一個Pub Discovery App中萨醒,SearchStore被用來跟蹤被搜索的item,搜索結果以及搜索歷史。在同一個應用中苇倡,一個ReviewedStore同樣包含了瀏覽pub的列表以及必要的邏輯比如根據(jù)review排序富纸。

但是有一個重要的概念需要記住:Stores并不是倉庫雏节。它們的職責不是從一個外部源(API或者數(shù)據(jù)庫)獲取數(shù)據(jù)胜嗓,而跟蹤actions提供的數(shù)據(jù)高职。

那么钩乍,F(xiàn)lux application是如何獲得數(shù)據(jù)的呢?

網絡請求與異步調用

在第一幅Flux示意圖中我有意跳過了一部分:網絡調用怔锌。接下來的示意圖完善第一幅圖并添加了更多細節(jié):

異步網絡調用是被一個Actions Creator觸發(fā)的寥粹。一個Network適配器完成相應API的異步調用并且返回結果給Actions Creator。

最終Actions Creator分發(fā)帶有返回數(shù)據(jù)的相應類型的Action埃元。

把所有網絡工作和異步工作獨立于Stores之外有兩個主要的優(yōu)點:

(1)你的Stores是完全同步的:這讓Stores中的邏輯更容易跟蹤涝涤。Bug也更容易跟蹤。同時岛杀,因為所有的狀態(tài)變化都是同步的,那么Store的測試變的非常簡單:啟動actions然后等待期望的結果

(2)所有的action都是從一個Action Creator觸發(fā)的:在一處單一的點創(chuàng)建與發(fā)起所有用戶操作可以大大簡化尋找錯誤的過程。忘掉在多個類中尋找某個操作的源頭吧哗脖,所有的事情都是在這里發(fā)生的。同時辨宠,因為異步調用發(fā)生在這之前,所有來自于ActionCreator的東西都是同步的货裹。這大大提高了代碼的可跟蹤與可測試性嗤形。

演示代碼:To-Do應用

在這個例子中,你將看到一個使用Flux架構的典型的To-Do應用弧圆。

我讓項目盡量簡單赋兵,只演示這個架構如何能夠產生組織良好的app。

對于實現(xiàn)的一些評價:

(1)Dispatcher的實現(xiàn)是通過Otto Bus搔预。但是幾乎任何bus都是可以的霹期。Flux架構本身在這個事件上有一定限制,我在這里沒有采用斯撮。原本Flux的定義中经伙,前一個事件沒有完成之前就

開始分發(fā)下一個事件是不允許的,會拋出一個異常勿锅。為了讓項目簡單帕膜,我沒有采用。

(2)有一個ActionsCreator類幫助創(chuàng)建Action,并把它們post給Dispatcher溢十。這在Flux中時相當普遍的模式垮刹,可以讓事情變的有序。

(3)Actions類型只是String常量张弛。也許這不是最好的實現(xiàn)荒典,但是它快速并且有助于事情的簡單化。

同樣的還有Actions數(shù)據(jù):它們只是以String類型為key,Object為值的HashMap吞鸭。這會導致Stores中轉換成實際數(shù)據(jù)的時候發(fā)生丑陋的類型轉換寺董。而且顯然這也不是類型安全的,但這也是為了讓我們的例子更好理解刻剥。

總結

在安卓應用中其實不存在最佳架構的說法遮咖。不過存在適合你當前app的最佳架構。這個架構可以讓你和團隊其他成員協(xié)作起來更輕松造虏,按時完成項目御吞,盡可能的保持高質量與較少的bug。

我相信Flux對于以上提到的特點都有很好的支持漓藕。

源碼

https://github.com/lgvalle/android-flux-todo-app

擴展閱讀:

Facebook Flux Overview

Testing Flux Applications

Flux architecture Step by Step

Async Requests and Flux

Flux and Android

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末陶珠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子享钞,更是在濱河造成了極大的恐慌揍诽,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異暑脆,居然都是意外死亡交排,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門饵筑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埃篓,“玉大人,你說我怎么就攤上這事根资〖茏ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵玄帕,是天一觀的道長部脚。 經常有香客問我,道長裤纹,這世上最難降的妖魔是什么委刘? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮鹰椒,結果婚禮上锡移,老公的妹妹穿的比我還像新娘。我一直安慰自己漆际,他們只是感情好淆珊,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奸汇,像睡著了一般施符。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擂找,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天戳吝,我揣著相機與錄音,去河邊找鬼贯涎。 笑死听哭,一個胖子當著我的面吹牛,可吹牛的內容都是我干的柬采。 我是一名探鬼主播欢唾,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼且警,長吁一口氣:“原來是場噩夢啊……” “哼粉捻!你這毒婦竟也來了?” 一聲冷哼從身側響起斑芜,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤肩刃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盈包,經...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡沸呐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呢燥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崭添。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖叛氨,靈堂內的尸體忽然破棺而出呼渣,到底是詐尸還是另有隱情,我是刑警寧澤寞埠,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布屁置,位于F島的核電站,受9級特大地震影響仁连,放射性物質發(fā)生泄漏蓝角。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一饭冬、第九天 我趴在偏房一處隱蔽的房頂上張望使鹅。 院中可真熱鬧,春花似錦昌抠、人聲如沸并徘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麦乞。三九已至,卻和暖如春劝评,著一層夾襖步出監(jiān)牢的瞬間姐直,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工蒋畜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留声畏,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓姻成,卻偏偏與公主長得像插龄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子科展,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內容