接触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. Android(安卓)MVP模式 初步理解
  2. Android调用天气接口(和风天气)
  3. 动手撸一个Android路由框架LuRouter
  4. Android(安卓)MVC 架构详解
  5. 简述MVC框架模式以及在你(Android)项目中的应用
  6. API接口JWT方式的Token认证(下),客户端(Android)的实现
  7. [程序猿感悟] Android平台开发中的重构三步走
  8. Android透明状态栏与沉浸模式全解
  9. 刷中兴N760经历,最靠谱的方式刷Android有感

随机推荐

  1. android实现下拉列表 ListView
  2. android中文字体
  3. Android(安卓)TTS学习——独特你的名字
  4. Android 日志工具类
  5. Android如何分析和研究Monkey Log文件
  6. android ViewPager之OnPageChangeListene
  7. AndroidTimer使用(三)-补充篇
  8. Google code android开源项目(二)
  9. android 自定义toast停留时间
  10. bug: Could not get resource 'https://j