Android MVP淺析

前言

近期一直在看設計模式相關的資料,每逢結尾都會介紹到 MVC 模式,而最近比較火的卻是 MVP 和 MVVM ,更有甚者,將 MVP 和 MVVM 結合起來形成了 MVPVM ,大神的造詣總是讓俺望其項背,下面就結合自己的學習,淺析 MVP。

從哪里開始學習呢?當然是從 Google 自身開始咯,Google 推出了自己的官方 MVP 架構例子。源碼地址

相關翻譯

今天就主要來看看官方寫的最基礎的 MVP 的例子 todo-mvp。本文不打算講解里面代碼的具體實現,只是從宏觀角度看一下,Google是如何實現 MVP 模式的,細節(jié)需要自己慢慢體會,每個人的體會都會不一樣的。(里面還涉及到了測試相關的東西)

剖析

Step One

首先從 Github 上 clone 下來,然后本地運行起來,效果如下

這是一個簡版的便簽,相關數據存儲在本地數據庫中。知道這個 App 是干嘛的,對下面分析相關代碼就好理解了。

Step Two

看代碼,找關系,官方的代碼結構如下

看目錄

  • addetitask:添加/修改任務功能
  • statistics:分析功能(位于側邊欄上)
  • taskdetail:查看任務詳情
  • tasks:首頁界面,展示任務列表
  • data:數據操作相關
  • util:工具類相關

通過目錄,這個 App 的相關操作也就一目了然了,接下來就針對 task 目錄下的代碼進行分析,看看是如何體現 MVP 思想的。

Step Three

分析前,先認識一下 MVP ,至少了解一下代表的含義

MVP (Model-View-Presenter) 該模式包含以下幾個方面

  • View:負責繪制 UI 元素、與用戶進行交互(Activity/Fragment);
  • View interface:需要 View 實現的接口,View 通過 View interface 與 Presenter 進行交互,降低耦合,方便進行單元測試;
  • Model:負責存儲、檢索、操縱數據(有時也實現一個Model interface 用來降低耦合);
  • Presenter:作為 View 與 Model 交互的中間紐帶,處理與用戶交互的負責邏輯。

先掌握上面的基礎概念就可以,下面進入正題

Step Four

task 目錄下包含了以下幾個文件

  • ScrollChildSwipeRefreshLayout:自定義控件,擴展了 SwipeRefreshLayout
  • TasksActivity:程序入口
  • TasksContract:關聯(lián)了 View 和 Presenter,是個接口
  • TasksFilterType:是個枚舉類,里面定義了 Tasks 列表的狀態(tài);
  • TasksFragment:展示 Tasks 列表等相關操作的 Fragment;
  • TasksPresenter: Presenter,負責關聯(lián) View 和 Model

它們的關系用類圖來表示,如下圖所示

其中數據類的相關 java 類簡化表示了,詳細的自行查閱 Github 上的內容

從上面可以看到,Google 首先定義了兩個接口文件 BaseView 和 BasePresenter,然后又通過 接口 TasksContract 進行關聯(lián),所有用到上面兩個接口的都是通過 TasksContract 進行管理。

看上面的圖,好像有點繁雜,眼花繚亂的感覺,那就先搬一張 MVP 模式基本的類圖,如下

那么結合上圖,怎么根據上面進行劃分呢,其實非常容易,如下

上面標的還不算特別好,其中 BaseView 也屬于 View 里面,BasePresenter 屬于 Presenter 范疇

如果大家仔細看的話,就會發(fā)現,View 和 Model 直接是沒有任何關聯(lián)的哦,而 Presenter 和 Model 和 View 都是有關聯(lián)的,現在在和上面標準的類圖進行對比,是不是就一目了然啦。如果大家對里面的代碼細節(jié)感興趣,請自行查閱源碼哦。

對了,說一點,里面的 TasksActivity 的作用就是將 Presenter 和 TasksFragment 關聯(lián)起來(不貼點代碼好像也不行了)

TasksFragment tasksFragment =
            (TasksFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);
    if (tasksFragment == null) {
        // Create the fragment
        tasksFragment = TasksFragment.newInstance();
        ActivityUtils.addFragmentToActivity(
                getSupportFragmentManager(), tasksFragment, R.id.contentFrame);
    }

    // Create the presenter
    mTasksPresenter = new TasksPresenter(
            Injection.provideTasksRepository(getApplicationContext()), tasksFragment);

    // Load previously saved state, if available.
    if (savedInstanceState != null) {
        TasksFilterType currentFiltering =
                (TasksFilterType) savedInstanceState.getSerializable(CURRENT_FILTERING_KEY);
        mTasksPresenter.setFiltering(currentFiltering);
    }

Step Five

再來審視一下 MVP

  • M:Model,數據相關,主要就是提供數據的存取功能,像一個數據倉庫。Presenter 需要通過 Model 層存、取數據。
  • V:View,用戶界面,也就是Activity、Fragment、View控件等,它持有 Presenter 的一個成員變量。通常 View 需要實現一個邏輯接口(示例就是這樣做的),將 View 上的操作會轉交 Presenter 來年實現。最后,Presenter 調用 View 的邏輯接口將結果返回給 View 元素。
  • P:Presenter,交互中間人。溝通 Model 和 View 的橋梁,將 Model 和 View 之間的關聯(lián)斬斷掉,改為 Presenter 進行聯(lián)絡。這也是和 MVC 模式最大的不同。

MVP 的優(yōu)點

  • 看類圖就知道,首先就是分離了 View 和 Model,降低了耦合
  • 易于維護、測試,一目了然,接口的存在,大大降低了測試的復雜度
  • 代碼的可閱性就變的容易了
  • 類型的職責明確,各司其職,應用 MVP 時,會感覺到,結構清晰明了,爽

說完優(yōu)點,肯定有缺點的,誰讓沒有一個模式都是金光閃閃,毫無缺點的。

  • Presenter 負責溝通 Model 和 View ,當然不可避免的就會“臃腫”起來
  • 有 View 的存在,就會有 Presenter 的存在,而在實際項目中,一個界面往往有很多的 View 構成,那么想想也是很“激動”的

最后

每個模式的出現,都會解決其他模式的缺點,卻又不可避免的帶來自身的缺點,然后等著下一模式的出現來解決上一模式的缺點,周而復始。也正是這樣的循環(huán),讓我們不斷的向更好的方向進步,例如: MVVM 的出現。

想要深入學習,查看具體實現方式,請自行下載相關代碼進行研究。

參考資料

Android開發(fā)藝術探索[M]. 電子工業(yè)出版社, 2015.487-494

Android官方MVP架構示例項目解析

Google Android MVP Pattern 知識整理

Android MVP模式 簡單易懂的介紹方式

如何設計MVP中的Presentation層

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容