MVP模式

来源:互联网 发布:淘宝达人合作平台 编辑:程序博客网 时间:2024/06/09 14:53

参考:

MVP模式在Android开发中的应用    

https://www.sdk.cn/news/2501  

Android开发中,Activity并不是一个标准的MVC模式中的Controller它的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。当我们将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由Presenter处理).

     MVP模式可以让显示界面和数据分离,我们开发的应用可以分离至少三层,这样也可以进行独立测试。有了MVP我们就可以从Activity中分离大部分代码,而且不用单元测试可以对每个模块进行单独测试了。

MVP Model – Presenter – View各部分之间的通讯,都是双向的,Presenter持有 ViewModel的抽象引用,作为中间人,处理业务逻辑,Model角色用于调取数据,而 View则用于展现和控制 UI,它们都由中间人P 调度。抽象的好处前面说了,如果 MV有改变,只要换一个实现者就好了,对于 P,可以继续把它们当成提供一样的可调用方法对象。

对于包的结构,如果项目比较小,可以把不同的 Presenter置于同一个 package下,而如果页面数很多项目模块很多,则可以每一个模块分一套 MVP packages

现在我们只要在 ActivityFragment中的生命周期简单做一些 UI组件初始化等布置,然后一些业务逻辑工作就请求 Presenter去完成,Presenter内部持有 ViewModelActivityViewMVP中的 View) 的实现,于是Presenter 调用Model 去请求得到数据库或网络数据,完成之后再调用View 改变UI 的方法,或者把数据交给View 去展现。如此,每个角色的代码都会变得很简洁、明确。而且,将业务逻辑放到Presenter 中去,可以避免当Activity 退出而后台线程仍然引用着Activity,致使资源无法被系统回收从而引起内存泄露。

对于屏幕旋转 Activity重建和内存泄漏等问题,MVP能够更好地处理。当 Activity销毁的之前,可以把 Presenter中的引用去除,因此不会在切换屏幕的时候发生内存泄漏,而且没必要去 unsubscribe请求。具体推荐大家看看这篇文章:使用 MVP和后台任务


 MVP模式里通常包含4个要素:

     (1)View:负责绘制UI元素、与用户进行交互(Android中体现为Activity);

     (3)Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);

     (4)Presenter:作为ViewModel交互的中间纽带,处理与用户交互的负责逻辑。

MVP模式:

· View不直接与Model交互,而是通过与Presenter交互来与Model间接交互

· PresenterView的交互是通过接口来进行的,更有利于添加单元测试

· 通常ViewPresenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑    

   MVC模式:

· View可以与Model直接交互

· Controller是基于行为的,并且可以被多个View共享

· 可以负责决定显示哪个View

回想一下你在开发Android应用时是如何对代码逻辑进行单元测试的?是否每次都要将应用部署到Android模拟器或真机上,然后通过模拟用户操作进行测试?然而由于Android平台的特性,每次部署都耗费了大量的时间,这直接导致开发效率的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)进行交互的,这说明我们可以通过自定义类实现这个interface来模拟Activity的行为对Presenter进行单元测试,省去了大量的部署及测试的时间。

MVC → MVP

当我们将Activity复杂的逻辑处理移至另外的一个类(Presenter)中时,Activity其实就是MVP模式中的View,它负责UI元素的初始化,建立UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由 Presenter处理)。

MVP的Presenter是框架的控制者,承担了大量的逻辑操作,而MVC的Controller更多时候承担一种转发的作用。因此在App中引入MVP的原因,是为了将此前在Activty中包含的大量逻辑操作放到控制层中,避免Activity的臃肿。

两种模式的主要区别:

· (最主要区别)View与Model并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVC中View可以与Model直接交互

· 通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。而Controller是基于行为的,并且可以被多个View共享,Controller可以负责决定显示哪个View

· Presenter与View的交互是通过接口来进行的,更有利于添加单元测试。

因此我们可以发现MVP的优点如下:

1、模型与视图完全分离,我们可以修改视图而不影响模型;

2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;

3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;

4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

具体到Android App中,一般可以将App根据程序的结构进行纵向划分,根据MVP可以将App分别为模型层(M),UI层(V)和逻辑层(P)。

UI层一般包括Activity,Fragment,Adapter等直接和UI相关的类,UI层的Activity在启动之后实例化相应的Presenter,App的控制权后移,由UI转移到Presenter,两者之间的通信通过BroadCast、Handler或者接口完成,只传递事件和结果。

举个简单的例子,UI层通知逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)自己决定应该用什么行为进行响应,该找哪个模型(Model)去做这件事,最后逻辑层(Presenter)将完成的结果更新到UI层。

ANDROID MVP 模式 简单易懂的介绍方式

MVP模式的核心思想:

MVPActivity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model

这就是MVP模式,现在这样的话,Activity的工作的简单了,只用来响应生命周期,其他工作都丢到Presenter中去完成。从上图可以看出,PresenterModelView之间的桥梁,为了让结构变得更加简单,View并不能直接对Model进行操作,这也是MVPMVC最大的不同之处。

MVP模式的作用

·分离了视图逻辑和业务逻辑,降低了耦合

·Activity只处理生命周期的任务,代码变得更加简洁

·视图逻辑和业务逻辑分别抽象到了ViewPresenter的接口中去,提高代码的可阅读性

·Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试

·把业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM

其中最重要的有三点:

Activity 代码变得更加简洁

相信很多人阅读代码的时候,都是从Activity开始的,对着一个1000+行代码的Activity,看了都觉得难受。

使用MVP之后,Activity就能瘦身许多了,基本上只有FindViewSetListener以及Init的代码。其他的就是对Presenter的调用,还有对View接口的实现。这种情形下阅读代码就容易多了,而且你只要看Presenter的接口,就能明白这个模块都有哪些业务,很快就能定位到具体代码。Activity变得容易看懂,容易维护,以后要调整业务、删减功能也就变得简单许多。

方便进行单元测试

一般单元测试都是用来测试某些新加的业务逻辑有没有问题,如果采用传统的代码风格(习惯性上叫做MV模式,少了P),我们可能要先在Activity里写一段测试代码,测试完了再把测试代码删掉换成正式代码,这时如果发现业务有问题又得换回测试代码,咦,测试代码已经删掉了!好吧重新写吧……

MVP中,由于业务逻辑都在Presenter里,我们完全可以写一个PresenterTest的实现类继承Presenter的接口,现在只要在Activity里把Presenter的创建换成PresenterTest,就能进行单元测试了,测试完再换回来即可。万一发现还得进行测试,那就再换成PresenterTest吧。

避免 Activity的内存泄露

Android APP 发生OOM的最大原因就是出现内存泄露造成APP的内存不够用,而造成内存泄露的两大原因之一就是Activity泄露(Activity Leak)(另一个原因是Bitmap泄露(Bitmap Leak))。

Java一个强大的功能就是其虚拟机的内存回收机制,这个功能使得Java用户在设计代码的时候,不用像C++用户那样考虑对象的回收问题。然而,Java用户总是喜欢随便写一大堆对象,然后幻想着虚拟机能帮他们处理好内存的回收工作。可是虚拟机在回收内存的时候,只会回收那些没有被引用的对象,被引用着的对象因为还可能会被调用,所以不能回收。

Activity是有生命周期的,用户随时可能切换Activity,当APP的内存不够用的时候,系统会回收处于后台的Activity的资源以避免OOM

采用传统的MV模式,一大堆异步任务和对UI的操作都放在Activity里面,比如你可能从网络下载一张图片,在下载成功的回调里把图片加载到Activity ImageView 里面,所以异步任务保留着对Activity的引用。这样一来,即使Activity已经被切换到后台(onDestroy已经执行),这些异步任务仍然保留着对Activity实例的引用,所以系统就无法回收这个Activity实例了,结果就是Activity LeakAndroid的组件中,Activity对象往往是在堆(Java Heap)里占最多内存的,所以系统会优先回收Activity对象,如果有Activity LeakAPP很容易因为内存不够而OOM

采用MVP模式,只要在当前的ActivityonDestroy里,分离异步任务对Activity的引用,就能避免Activity Leak

0 0
原创粉丝点击