MVP架构模式

来源:互联网 发布:炫酷戒指女淘宝 编辑:程序博客网 时间:2024/06/05 14:50

MVP架构模式

一、简介

概述:MVP 全称 Model View Presenter。MVP模式可以分离显示层和逻辑层。它们之间通过接口进行通信,降低耦合。理想化的MVP模式可以实现同一份逻辑代码搭配不同的显示界面,因为它们之间并不依赖于具体,而是依赖于抽象。这就带来了良好的可扩展性、可测试性,保证了系统的整洁性、灵活性。

MVP模式的三个角色:

1.Presenter–交互中间人

Presenter从Model层检索数据后,返回给View层,是的View和Model之间没有耦合,也将业务逻辑从View角色上抽离出来。

2.View–用户界面

View通常是指Activity、Fragment或者某个View控件,它含有一个Presenter的实例。通常View需要实现一个逻辑接口,View上的操作通过Presenter的成员变量转交Presenter进行实现,最后,Presenter调用View的逻辑接口将结果返回给View。

3.Model–数据处理

Model角色主要是提供数据的处理功能。Presenter通过Model层存储、获取数据。说白了,Model就是封装了数据库或者网络数据的角色,或者两种数据获取方式的集合。

MVP结构图:

二、MVP的简单例子

我们来自己写个小例子,以Login为例,View发起login请求,将请求参数传给Presenter,Presenter传给Model层处理,Model层将用户信息回传给Presenter,Presenter回传给View层,View显示到界面上。

2.1 LoginEntity

public class LoginEntity {    private String userId;    private String userName;    private String userphone;    public String getUserId() {    return userId;    }    public void setUserId(String userId) {    this.userId = userId;    }    public String getUserName() {    return userName;    }    public void setUserName(String userName) {    this.userName = userName;    }    public String getUserPhone() {    return userphone;    }    public void setUserPhone(String userphone) {    this.userphone = userphone;    }}

2.2 View层接口

View层的逻辑接口,用于Presenter层回调。

2.3 Presenter层接口

定义两个接口,一个用于View层调用,一个用户Model层回调。

2.4 Model层接口

用于Presenter调用

2.5 View层调用

  • V层包含P层实例,通过P层实例调用P层方法,将请求传给P层。

  • V层实现了V的逻辑接口,用于获取返回结果,并将返回结果显示在界面上。


2.6 Presenter层调用

  • P层实现了两个接口,一个用于接收V层请求,一个用于M层回调。

  • P层包含M层实例,通过M层实例调用M层方法,将请求传给M层。

  • p层的构造方法需要传入V层接口对象,用于V层回调。

2.7 Model层调用

  • M层实现了一个接口,用于接收P层的请求。

  • M层的构造方法需要传入P层接口对象,用于P层回调。

运行效果:

备注:MVP并不是一个标准化的模式,它有很多实现方式,我们也可以根据需求去修正MVP的实现方式,只要保证我们是通过Presenter将View与Model解耦合,降低类型复杂度、各个模块可以独立测试、独立变化,方向就是正确的。

三、MVP与Activity、Fragment的生命周期

问题描述:由于Presenter经常性的需要执行一些耗时操作,例如,请求网络数据。而Presenter持有了Activity的强引用,如果在请求结束之前Activity被销毁了,那么由于网络请求还没有返回,导致Presenter一直持有Activity对象,使得Activity对象无法被回收,此时就发生了内存泄漏。

解决方案:通过弱引用和Activity、Fragment的生命周期来解决。

3.1 创建BasePresenter抽象类

  • 它是一个泛型类,泛型类型为View角色要实现的接口类型。

View类型通过BasePresenter的泛型类型传递进来,Presenter对这个View持有弱引用。

3.2 创建MVPBaseActivity基类

  • 通过这个基类的生命周期函数来控制它与Presenter的关系。

MVPBaseActivity含有两个泛型参数,第一个是View接口类型,第二个是Presenter的具体类型。通过泛型参数,使得一些通用的逻辑可以被抽象到MVPBaseActivity类中。例如,在MVPBaseActivity的onCreate函数中,会通过createPresenter函数创建一个具体的Presenter,这个Presenter的类型就是BasePresenetr < V > 类型。构建Presenter之后调用attachView函数与Activity建立关联。而在onDestory函数中,则会与Activity解除关联,从而避免内存泄漏。

疑问:如果在onDestory函数中解除了对Activity的引用,就没有必要使用弱引用了。解答:并不是任何情况下Activity的onDestory都会被调用,一旦这种情况发生,弱引用也能够保证不会造成内存泄漏。

通过MVPBaseActivity的封装维护Presenter和View关联关系的代码,使得子类可以避免重复的代码,同时又避免了Activity的内存泄漏问题。我们可以根据需求为Fragment、FragmentActivity等类型都建立一个类似这样的基类。