1. 程式人生 > >Android開發MVP模式--專案實戰

Android開發MVP模式--專案實戰

1 前言

蘇寧+App是蘇寧易購集團零售雲研發中心分銷研發中心主要產品之一,由於專案處於初期階段,業務邏輯複雜,導致業務需求變動快,常常在開發甚至測試過程中出現介面或者後臺介面調整的情況。
App客戶端如何在外部需求不斷變化的情況下,降低模組耦合,儘可能減少每次程式碼修改量,一方面減少開發人員的工作量,另一方面降低測試工程師的工作量,最終順利完成專案迭代開發。

2 為什麼使用MVP模式

相信在2014年之前,絕大部分人開發Android應用,都是使用的MVC模式,M跟V一般沒有什麼問題,Controller層也就是對應Activity類,它的首要職責是載入應用的佈局和初始化使用者介面,並接受和處理來自使用者的操作請求,進而作出響應。
隨著介面及其邏輯的複雜度不斷提升,Activity類的職責不斷增加,以致變得龐大臃腫,開啟以前專案的Activity,超過2000行的不在少數。
另外,由於專案的特殊性,網際網路產品講究速度,尤其是新產品,上線的時間會決定你在市場上的佔有量。
App的理想情況是UED做好視覺稿,後臺介面準備完畢,客戶端同學一邊做頁面一邊除錯介面,做完自測後順利交付測試。但是,理想很豐滿,現實很骨感。
實際情況是,我們開始coding的時候,只有一份介面文件跟互動圖。我們需要思考的是,我們必須把介面和介面資料解耦,介面聯調和測試工作不能依賴介面的完成,當完成業務層程式碼後,就可以測試業務功能。基於上面的背景,我們選擇了MVP模式。

3 什麼是MVP模式

我們上面說的MVP架構,是Google開源的一個設計模式,主要是為了細分檢視(View)與模型(Model)的功能,讓View只做兩件事:
 完成使用者的互動;
 顯示介面佈局,同時讓Model做資料的處理,業務邏輯放到另外的一個類(Presenter)中。
下面做具體分析:
 M:M層,在專案中負責資料的處理,包括本地資料庫查詢,網路資料獲取都在這一層中完成。
 View:V層,在專案中是UI模組,也就是各種activity/fragment,負責繪製UI元素、與使用者進行互動。
 P:P層,在專案做為View與Model的橋樑,M跟V層不直接互動,M層在獲取到資料之後,傳遞到P,P層再通過介面回撥到View層,同樣,View層的點選等事件,通過P層去通知M層去處理。
如下圖所示:
這裡寫圖片描述

4 MVP模式應用實戰

4.1蘇寧+app專案結構圖:
這裡寫圖片描述
目前App整體專案架構如上圖所示,各個層次的介紹如下:
 【前端介面層】:介面相關佈局,如各種activity/fragment類。
 【業務邏輯層】:業務邏輯相關,如各種presenter類。
 【資料層】:資料相關,包括資料儲存,獲取,如各種model類。
 【執行服務層】:伴隨應用生命週期自動初始化,自動銷燬,提供一系列服務給其他業務模組呼叫,如各種service類。
 【業務框架層】:針對當前app跟業務有耦合度的公共方法,元件抽取。
 【基礎框架層】:跟業務無關的底層元件,可以給多個app同時使用。
 【系統層】:android系統底層。
通過上面的架構圖可以很直觀的看出,我們日常業務功能迭代的時候,主要修改或者新增的程式碼都在前面三層,這裡主要講前面三層的使用規範。

4.2目錄結構 :
下圖為使用MVP模式時,購物車確認訂單頁面的目錄結構:
這裡寫圖片描述
model————————————————————————————資料處理
presenter——————————————————————————–業務處理
task————————————————————————————–網路請求
ui—————————————————————————————–頁面
util—————————————————————————————當前模組公共類
view————————————————————————————–頁面重新整理回撥介面

4.3總體邏輯設計
如圖為購物車2介面,下面將圍繞該介面來講解如何用MVP實現具體業務功能。
這裡寫圖片描述
為了更加直觀看到MVP在當前業務中的使用,我們畫了類圖跟時序圖,通過類圖我們可以清楚類的設計,如下所示:
這裡寫圖片描述
通過下面的時序圖,我們可以很清楚的看到呼叫關係:
這裡寫圖片描述
通過上面兩張圖,我們可以看到MVP在當前業務中對應的角色以及呼叫關係,下面深入程式碼層面繼續講解。

4.程式碼實現

1)M層(model)專案中很多網路請求是重複的,比如很多頁面都會用到店鋪資訊介面,如果每個頁面都要在不同model寫一遍,那麼複用性很弱。
所以跟Google在Github釋出的mvpdemo不同,我們專案中每個網路介面都單獨寫成一個Task,以確認訂單頁面為例:model層定義模型抽象類(PSCShopCart2DataSource ),然後具體實現類(PSCShopCart2Repository )裡面呼叫Task,傳送網路請求。如下:
這裡寫圖片描述
這裡寫圖片描述

2)IView MVP模式中,M層跟V層不能直接通訊,資料是通過presenter層介面回撥到V層中。一般情況下,IView裡面的介面就對應V層的功能。
這邊會有人覺得特別複雜的場景會出現很多介面的情況,當然如果真出現這種情況,該合併的介面還是要合併,到activity中做簡單的處理也是可以的,實際開發中一定不能被框架限制,不管什麼模式都是為了業務正常迭代。
程式碼如下:
這裡寫圖片描述
這裡寫圖片描述

3)P層(presenter)原先雜糅在activity/fragment裡面的業務邏輯移到presenter中,同時presenter做為M和V之間互動的橋樑。
由於activity跟fragment生命週期不同,會影響一些彈出框關閉的時機,所以專案中,activity跟fragment分別定義了一套基礎業務抽象類,這邊以activity基礎業務抽象類來演示,所有的activity中用到的presenter都繼承PSCBaseActivityPresenter:
這裡寫圖片描述
PSCActivityNetTask主要做網路任務監聽並回調到presenter中,還會設定生命週期監聽,用於顯示載入框。
這裡寫圖片描述
presenter接受到網路回撥後,根據介面返回的資料做業務處理,成功或者失敗分別通過介面回撥到View層,重新整理介面。
這裡寫圖片描述
這裡寫圖片描述

4)V層(view)相信大多數App都會有baseActivity作為基類,將Activity公共部分抽取出來進行封裝。
蘇寧的基類叫做SuningActivity/SuningFragment,每個介面都需要把view跟presenter繫結/解綁,這些都可以放到基類中,然後定義protected abstract T createPresenter();將建立Presenter步驟交給子類實現。
程式碼量比較大,這邊做了刪減,僅保留MVP相關的程式碼,如下:
這裡寫圖片描述
activity實現上面定義的IView,實現資料的接收,同時會在當前類中建立presenter,通過presenter方法呼叫model中的網路請求。
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

5 總結

以上內容就是我們對於MVP架構的理解,並在蘇寧+專案中實戰後分享給大家。
MVC,MVP,MVVM不管何種模式,都可以實現功能,選擇相應模式的時候,要看相對於目前業務來說的,何種模式能夠封裝變化,讓各模組解耦,實現獨立變化,減少日後的維護工作和暗藏的風險。
當然我們也不能陷入模式的陷阱,為了使用模式而去套模式。沒有好的框架,只有適合的框架,如果大家發現我們當前專案中對於MVP的使用不對或者不完善的地方,歡迎提出來,我們一起探討。

如有錯誤歡迎指出來,一起學習。

交流討論群
群號:469890293