初识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的解释到案例就结束了,如果还有不太懂得童鞋可以留言。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值