美團點評Android客戶端融合架構演進之路

一 背景

點評美團合并之后,業務需要整合,我們部門的幾條業務需要往美團平臺遷移,為了降低遷移成本,開發和維護成本,以及將來可能要做的單元測試,需要對架構進行相應的調整。之前的代碼都堆在Activity或Fragment里面,UI,業務,數據混合在一起,就使得難以單獨的復用和擴展、測試。


二 目標

代碼復用

UI獨立

業務獨立

數據獨立

可測試

三 簡潔架構

這里先引入簡潔架構的概念,該架構由Uncle Bob提出,他認為一個架構應該具有以下特性

框架獨立性

架構不應該依賴于現有的library,這樣可以讓你像工具一樣去使用架構,而不是對你的系統添加約束

可測試

業務邏輯可以在不依賴UI,數據庫,網絡服務等其它外部因素的情況下進行測試

UI獨立性

在不變動系統其它部分的情況下,可以很方便的改變UI,比如,在沒有變動任何業務邏輯的情況下web ui可以被替換成console ui

數據庫獨立性

可以很自如的在Oracle,SQL Server之間切換,而不涉及業務邏輯

任何外部代理??櫚畝懶⑿?/strong>

業務邏輯應該不需要知道外部世界的任何事情


內層不應該知道外層的任何情況

各層之間通過接口交互

上層依賴下層,但依賴于接口

應用中最重部分就是業務邏輯層。它負責解決應用所真正想解決的問題。該層不包含任何框架相關的代碼,因此其代碼應該可以在沒有模擬器的情況下獨立運行。這樣,測試、開發和維護業務邏輯代碼就要容易很多。而這就是干凈架構的主要優勢。

下面簡單對以上幾個概念進行簡單的介紹

Entities

數據部分,一個Entity可以是一個帶有方法的對象,或者一個數據結構和方法的集合

Use Cases

該層包含了應用特定的業務規則,封裝了應用中所有的use cases。這些use cases從entities組裝數據流,傳遞給業務使用。

該層的變更不應該影響到Entities,也不希望該層會被database,UI,或者其它通用框架的外部變化所影響到,該層應該獨立于這些部分。

Interface Adapters

該層是一些為了便于use cases和entities的數據轉換的適配器。這一層包含GUI的MVC架構,展示層,Views和Controllers都屬于該層。models更傾向于在controllers和use cases之間傳遞的數據結構,然后從use cases傳遞給Presenter和Views。

上面的這些原則足以構建高內聚,低耦合,可擴展的應用

四 Android架構探索

一個應用基本可以劃分為3個部分,UI,業務,和數據,而在移動端來說,更注重UI的展示,復雜的業務通常放在服務端。

針對這3部分,如何進行設計呢?

可以參考上面的基本原則 ,把整個項目拆分成3個不同的層級:

數據層業務層展示層

每一層保持功能獨立,上層依賴下層,但依賴于接口,而不是具體。每一層擁有自己的數據模型,做到依賴獨立。

4.1 表現層(Presentation Layer)

常見的模式有MVP,MVC,MVVM

表現層除了UI相關邏輯,不應該含有任何邏輯,這一層應該很輕,數據的獲取和業務處理應該交給業務層和數據層,Presenter在該層由Use Cases組裝,Use Cases會在新的線程執行一個任務并使用一個帶有數據的回調用于渲染view,

4.2 業務層 (Business logic(Domain) Layer)

業務層可能有些模糊,哪些應該屬于該層呢?

按照MVP的方式劃分,很容易理解的是,所有的業務邏輯放到P中即可。但實際開發中,你會發現,稍微復雜的業務,P層的代碼就會變得非常臃腫。我認為P的角色作為業務邏輯的組裝更合適。業務邏輯可以進行相應的封裝,比如

另外業務層應該是純java代碼,對android平臺沒有任何依賴,業務層向外暴露接口

4.3 數據層(Data Layer)

數據層提供了數據源,數據層也可以包括一些簡單的數據處理,比如JSON的封裝,一些model的轉換,外部不關心具體如何獲取數據的細節,只向數據層拿數據。比如下面展示了 倉庫模式(Repository Pattern)來實現數據層,它的策略是采用工廠模式,傳遞不同的條件參數,獲取不同的數據。


4.4 測試 (Testing)

基于上面的架構,我們更容易進行測試,不同的分層之間完全獨立,每一層也有自己相應的測試方案:

Presentation Layer:使用Android自帶的instrumentation和espresso做集成和功能測試。

Domain Layer:JUnit+mockito做單元測試。

Data Layer:Robolectric(這一層開始有Android相關的依賴)+junit+mockito做單元和集成測試

五 表現層架構

MVC

Model–View–Controller (MVC) is a software architectural pattern for implementing user interfaces.*

MVP,MVC,MVVM都是表現層的一種模式

這些架構相對于傳統的開發方式,門檻高些,要想深入掌握和更高層次的理解各個層的職責,需要一定積累,對于一些簡單的場景并不是一種好的方案,復雜的業務場景則會從中得到很多好處。

這些模式的好處

關注點分離,職責明確

o UI – 負責UI的渲染

o Presenter/controller – 負責響應UI事件并和Model交互

o Model – 負責業務行為和狀態管理

代碼重用性

關注點和責任分離之后,各層獨立,可以增加代碼的可用性

測試驅動

易于測試,只要寫一個實現了ViewInterface的類即可測試,而不需依賴android平臺

隱藏數據訪問

使用這種模式之后,數據的訪問代碼就被劃分到data層

擴展性高,可適配

將代碼分離到Presenter,Controller和Model中,可以更自由的適配

5.1 MVP

這里簡單的介紹下MVP的基本元素

M:數據實體,封裝數據

V:視圖的渲染,事件的響應

P:中間層,作為與M和V通訊的橋梁,組裝業務邏輯

在MVP模式里通常包含4個要素

(1)View: 負責繪制UI元素、與用戶進行交互(Activity或Fragment);

(2)View interface: View需要實現的接口,View通過View interface與Presenter進行交互

(3)Model: 業務Bean

(4)Presenter: 作為View與Model交互的紐帶,承載了大部分的復雜邏輯

5.2 MVP vs MVC

相同點

分離了不同組件之間的責任,降低了View和Model之間的耦合

不同點

MVP中,View與model之間的耦合更低,不容許View直接訪問Model,通過Presenter來交互,更加容易進行單元測試,因為View是通過接口來交互

通常View與Presenter的關系是一對一,復雜的View可能有多個Presenter

MVC可以決定展示哪個View,Controller依賴于行為,而且可以被多個View共用

5.3 MVP vs MVVM

MVP單項綁定,而MVVM采用雙向綁定(data-binding),View的變動,自動反映在 ViewModel,Model的變動也會反映到View中

其實MVP中Model是很輕的,數據的獲取和處理屬于架構中的數據層和業務層,所以這一點并不是很讓人能夠理解。

本篇文章主要是對android架構的探索,目前我們采用的是data+domain+MVP這種架構模式。


文/xhmj12(簡書作者)

上一篇: 滴滴 Android 插件化的實踐之路

下一篇: Andromeda OS 來了,Android 再見?

分享到: 更多
北京福彩赛车开奖时间 梅苏特厄齐尔 ag电子游戏网址导航 pk10玩法规则奖金 三分pk10走势图软件 红马计划软件手机版v1.02 网球即时比分直播 山西时时彩 双色球开奖出球顺序 加拿大pc28稳赚 体彩5码遗漏 即时比分球探网手机版 2017赛车pk10稳赢公式 快3赚钱投注方法 必富娱乐是不是倒闭了 北京pk赛车官网数据