提起MVP架构模式,大家可能首先想到的是它的“前辈”MVC模式。MVC由Model、View、Controller组成,请求从Controller进入后进行业务判断,然后交给Model或View进行处理。这本身没什么,但是应用在Android程序中时,大家就会发现,Activity既担任了Controller的角色进行业务筛选,又担任了View的角色进行界面展示,甚至有些时候还会担任Model的角色加载数据。这就使的Activity中的代码变得很多很长,而且功能杂乱,不便区分。怎么办呢?于是,MVP模式就诞生了。

  MVP由Model、View和Presenter组成,和MVC相似,MVP中的Model层也是用来加载数据的,View层也是用来展示界面的,MVP中独有的Presenter是用来连接Model和View两层,起到解耦的作用。下图展示了MVC模式和MVP模式的工作流程上的比较:

  从图中可以看到,MVP模式中的View层和Model层之间没有连线,即这两层之间没有直接的关联,它们之间的交互是通过Presenter来完成的,这样就实现的View和Model两层的解耦。具体的MVP内部的工作流程如下图所示:

  可以看到,用户首先在View层中进行操作,将用户动作传到Presenter中,Presenter将动作传递到Model中进行处理,然后将处理结果传回到Presenter,再由Presenter相应到View中。

  MVP模式的整体架构是通过接口来搭建的,我们需要一个整体的架构管理类Contract来管理Model、View、Presenter这三个接口,Model类、View类和Presenter类都分别实现这三个接口。Presenter中持有Model和View的引用,Presenter中的所有方法都会调用Model中对应的方法进行处理;Model中写实际代码;View是被Activity实现的,其中持有一个Presenter的引用,所有方法都会调用Presenter的对应方法。

  下面贴出一个简单的DEMO中的代码。

  DEMO的界面非常简单,只有一个按钮,当我们点击按钮的时候弹出一个Toast,就是这么一个简单的DEMO,我们尝试用MVP模式来搭建,编写。

  首先我们需要一个接口的统一管理类MainContract,这个类中包含了M、V、P三个接口,接口中定义抽象方法。这里我们只打算有一个方法,即按钮点击事件onButtonClicked()方法。代码如下:

public class MainContract {

    interface View {
void onButtonClicked(String text);
} interface Model {
void onButtonClicked(Context context, String text);
} interface Presenter {
void onButtonClicked(Context context, String text);
}
}

  有了接口之后,我们让M、V、P三层的具体类来实现这三个接口,这三个类分别是:M层对应MainModel,P层对应MainPresenter,V层对应MainActivity。

  我们来编写MainPresenter类中的代码,首先需要让它实现MainContract类中的Presenter接口,然后为它设置两个属性,一个是Model,一个是View,在构造方法中传入View,并初始化Model,最后实现Presenter接口中的方法并调用Model中的对应方法实现。MainPresenter类中的代码如下:

public class MainPresenter implements MainContract.Presenter {
private MainContract.Model model;
private MainContract.View view; public MainPresenter(MainContract.View view) {
this.view = view;
this.model = new MainModel();
} @Override
public void onButtonClicked(Context context, String text) {
model.onButtonClicked(context, text);
}
}

  接下来是MainModel类中的代码了。MVP中的所有具体逻辑实现的代码都是在Model层中编写的,因此在MainModel实现Model接口的onButtonClicked()方法中,我们按照需求弹出一个Toast即可。代码如下:

public class MainModel implements MainContract.Model {
@Override
public void onButtonClicked(Context context, String text) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
}

  最后就是View层的编写了。上面说过,View层的实现类就是Activity,View层中需要持有一个Presenter的引用,View层中的所有操作都调用Presenter层中对应的方法,而Presenter层都是调用Model层的代码,因此View层就算是间接的调用了Model层的代码。MainActivity中的代码如下:

public class MainActivity extends AppCompatActivity implements MainContract.View {
private MainPresenter presenter = new MainPresenter(MainActivity.this); @InjectView(R.id.btn)
protected Button button; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化ButterKnife
ButterKnife.inject(MainActivity.this);
} @OnClick(R.id.btn)
protected void click() {
onButtonClicked("Button Clicked!!!!");
} @Override
public void onButtonClicked(String text) {
presenter.onButtonClicked(MainActivity.this, text);
}
}

  到此为止,MVP的一个简单的DEMO就完成了。MVP只是一种思路,每个人都有每个人的理解,因此架构的搭建会有所不同,但整体的目标是不变的,那就是让Activity中的View层和Controller层分离开来,减少Activity中的代码。

  当然,MVP模式也有缺点,那就是每创建一个Activity,就需要再创建Contract、Model、Presenter三个类,会大大增加项目中的类的个数。

【Android - 框架】之MVP模式的使用的更多相关文章

  1. [译]Google官方关于Android架构中MVP模式的示例

    概述 该示例(TODO-MVP)是后续各种示例演变的基础,它主要演示了在不带架构性框架的情况下实现M-V-P模式.其采用手动依赖注入的方式来提供本地数据源和远程数据源仓库.异步任务通过回调处理. 注意 ...

  2. Android上实现MVP模式的途径

    今天我想分享我在Android上实现MVP(Model-View-Presenter)模式的方法.如果你对MVP模式还不熟悉,或者不了解为什么要在Android应用中使用MVP模式,推荐你先阅读这篇维 ...

  3. Google官方关于Android架构中MVP模式的示例续-DataBinding

    基于前面的TODO示例,使用Data Binding库来显示数据并绑定UI元素的响应动作. 这个示例并未严格遵循 Model-View-ViewModel 或 Model-View-Presenter ...

  4. Android 中的MVP 模式

    MVP模式的核心思想: MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成功接口,Model类还是原来的Model. MVC 其中View层其实就是程序的UI界面,用于向用户展示 ...

  5. Android开发之MVP模式的使用

    前几天发现,在Android项目代码里有一个Activity类行数居然有1000多行,而600行左右都是逻辑控制,真正和页面控件处理相关的代码不多,虽然可以用#region <>...#e ...

  6. android中的MVP模式

    1.建立bean public class UserBean { private String mFirstName; private String mLastName; public UserBea ...

  7. Android开发学习--MVP模式入门

    1.模型与视图完全分离,我们可以修改视图而不影响模型2.可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部3.我们可以将一个Presenter用于多个视图,而不需要改变Pr ...

  8. Android开发MVP模式解析

    http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html 在开发Android应用时,相信很多同学遇到和我一样的情况,虽然 ...

  9. Android架构篇--MVP模式的介绍篇

    摘要: 在MVVM成熟之前MVP模式在Android上有被神化的趋势,笔者曾经在商业项目中从零开始大规模采用过MVP模式对项目进行开发.在使用MVP模式进行开发的时候发现项目的结构模式对开发是有一定的 ...

  10. 浅谈Android架构之MVP,MVVM

    概述 MVP(Model-View-Presenter)是传统MVC(Model-View-Controller)在Android开发上的一种变种.进化模式.主要用来隔离UI.UI逻辑和业务逻辑.数据 ...

随机推荐

  1. 最近采用Instruments

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...

  2. Mysql JDBC Url参数说明useUnicode=true&characterEncoding=UTF-8

    MySQL的 JDBC URL 格式 for  Connector/J 如下例: jdbc:mysql://[host][,failoverhost...][:port]/[database] » [ ...

  3. dedecms织梦如何删除所有的文章?

    dedecms织梦如何删除所有的文章?dede一键删除所有文章的SQL命令:  DELETE FROM dede_addonarticle WHERE aid >= 1 and aid<= ...

  4. 搭建hive到eclipse里面

    (1)下载源码 git clone https://git-wip-us.apache.org/repos/asf/hive.git git clone https://github.com/apac ...

  5. 【C语言】printf函数详解

    C语言printf函数详解 一.相关基础知识 请求printf()打印变量的指令取决于变量的类型,例如打印整数用%d符号,打印字符用%c符号,这些符号称为转换说明(conversion specifi ...

  6. ios开发之C语言第一天

    最近在学习ios开发,先学习C语言,再学习OC和swift.正所谓"万丈高楼平地起",打好基础是很重要的,所以C语言也必须好好学习.学习中所使用的操作系统是OS X,开发工具是Xc ...

  7. Linux内核监控模块-2-系统调用表地址的获取(Linux内核版本3.13)

    那么在Linux内核2.6之后,不能直接导出sys_call_table的地址后,我们要如何获得系统调用表的地址,从而实现系统调用的截获呢. 先贴上我实现好的代码,然后再来讲解吧. modu.c #i ...

  8. windows server 2003 服务器

    服务器基本知识:可通过我的电脑属性里面查看服务器的系统. 设置固定Ip:本地连接(控制面板-网络连接)使用下面的Ip地址.通过ipconfig/all,查看DNS和ip. 远程访问服务器:我的电脑属性 ...

  9. Matlab聚类分析[转]

    Matlab聚类分析[转] Matlab提供系列函数用于聚类分析,归纳起来具体方法有如下: 方法一:直接聚类,利用clusterdata函数对样本数据进行一次聚类,其缺点为可供用户选择的面较窄,不能更 ...

  10. 去大公司还是去小公司工作——要进大公司的核心部门(提升视野,锻炼技能),远离没真本事的小公司,要自我驱动 good

    去大公司还是小公司工作?这个问题问大多数 IT 人都会选择前者.如果换一个问法,去大公司还是去初创公司(Startup)工作?或许有极小一部分人能改变一下决定 对于 IT 人来说,选择到大公司工作的理 ...