初識Android MVP模式

接觸Android MVP模式在好早之前,一直也沒有在項目中真正的實用。剛好有一個機會需要自己去做項目,然後就用上MVP。MVP用起來還是很方便,整個項目結構非常清晰,相比於傳統的MVC模式,MVP清晰分工,有太多有點了。這些其實是需要在實用以後才能體會到的,尤其是當項目很複雜的時候。

一、MVP介紹
在MVP模式裏通常包含4個要素:

  1. View:負責繪製UI元素、與用戶進行交互(在Android中體現爲Activity);
  2. View interface:需要View實現的接口,View通過View interface與Presenter進行交互,降低耦合,方便進行單元測試;
  3. Model:負責存儲、檢索、操縱數據(有時也實現一個Model interface用來降低耦合);
  4. Presenter:作爲View與Model交互的中間紐帶,處理與用戶交互的負責邏輯。
    這裏寫圖片描述

二、爲什麼使用MVP模式
在Android開發中,Activity並不是一個標準的MVC模式中的Controller,它 的首要職責是加載應用的佈局和初始化用戶界面,並接受並處理來自用戶的操作請求,進而作出響應。隨着界面及其邏輯的複雜度不斷提升,Activity類的 職責不斷增加,以致變得龐大臃腫。當我們將其中複雜的邏輯處理移至另外的一個類(Presneter)中時,Activity其實就是MVP模式中 View,它負責UI元素的初始化,建立UI元素與Presenter的關聯(Listener之類),同時自己也會處理一些簡單的邏輯(複雜的邏輯交由 Presenter處理).

另外,回想一下你在開發Android應用時是如何對代碼邏輯進行單元測試的?是否每次都要將應用部署到Android模擬器或真機上,然後通過模擬用 戶操作進行測試?然而由於Android平臺的特性,每次部署都耗費了大量的時間,這直接導致開發效率的降低。而在MVP模式中,處理複雜邏輯的 Presenter是通過interface與View(Activity)進行交互的,這說明了什麼?說明我們可以通過自定義類實現這個 interface來模擬Activity的行爲對Presenter進行單元測試,省去了大量的部署及測試的時間。

三、MVP與MVC的異同
MVC模式與MVP模式都作爲用來分離UI層與業務層的一種開發模式被應用了很多年。在我們選擇一種開發模式時,首先需要了解一下這種模式的利弊:

無論MVC或是MVP模式都不可避免地存在一個弊端:

  • 額外的代碼複雜度及學習成本。(這就導致了這兩種開發模式也許並不是很小型應用。

但比起他們的優點,這點弊端基本可以忽略了:

  • 降低耦合度
  • 模塊職責劃分明顯
  • 利於測試驅動開發
  • 代碼複用
  • 隱藏數據
  • 代碼靈活性

四、案例
這裏用一個案例來詳細介紹MVP的實用,當然這裏做一個基類封裝方便使用。

IPresenterView接口

/**
 * @author ttarfall
 * @date 2016-09-06 10:08
 */
public interface IPresenterView {
}

(當然這裏用了一個空的接口,其實是可以在裏邊加一些通用的方法)

BasePresenter基類

/**
 * 基礎basePresenter,用於IView接口的傳入,attach,dettach用於綁定與解綁IView,當Activity被銷燬的時候,及時解綁IView防止內存溢出
 * @author ttarfall
 * @date 2016-09-06 10:02
 */
public abstract class BasePresenter<T extends IPresenterView> {

    protected T paresenterView;

    public void attach(T mView) {
        this.paresenterView = mView;
    }

    public void dettach() {
        paresenterView = null;
    }
}

BaseMVPActivity基類

import android.os.Bundle;

/**
 * @author ttarfall
 * @date 2016-09-06 09:36
 */
public abstract class BaseMVPActivity<V extends IPresenterView, P extends BasePresenter<V>> extends BaseActivity {


    protected P presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        presenter = initPresenter();
        try {
            presenter.attach((V) this);
        } catch (Exception e){
            new ClassCastException(this.toString() +"實現IPresenterView或者IPresenterView子類接口");
        }
    }

    @Override
    protected void onDestroy() {
        presenter.dettach();
        super.onDestroy();
    }

    //實例化Presenter
    public abstract P initPresenter();
}

BaseMVPFragment基類

import android.os.Bundle;

/**
 * @author ttarfall
 * @date 2016-09-08 13:45
 */
public abstract class BaseMVPFragment<V extends IPresenterView, P extends BasePresenter<V>> extends BaseFragment {

    protected P presenter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        presenter = initPresenter();
        try {
            presenter.attach((V) this);
        } catch (Exception e) {
            new ClassCastException(this.toString() + "實現IPresenterView或者IPresenterView子類接口");
        }
    }

    @Override
    public void onDestroy() {
        presenter.dettach();
        super.onDestroy();
    }

    //實例化Presenter
    public abstract P initPresenter();
}

上邊是MVP做了一個簡單的封裝,接下來就是使用了。如圖
這裏寫圖片描述
IMainView源碼,當然這裏的ILoaddingView 接口也是繼承IPresenterView ,只不過增加了一個setLoading方法。
這裏寫圖片描述
MainPresenter部分源碼截圖,可以看到我這裏其實有3個mode,當然每一個mode都有自己實現的方法。
這裏寫圖片描述
mode存主要是獲取數據的和保存數據使用。這裏展示UserInfoMode的使用,IUserInfoMode展示提供的方法。
這裏寫圖片描述
最後就是IMainView需要在Activity或者Fragment中實現。然後就是Presenter通過IPresenter與Activity或者Fragment互動。
至此一整套MVP的解釋到案例就結束了,如果還有不太懂得童鞋可以留言。

發佈了37 篇原創文章 · 獲贊 26 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章