Android中的MVP

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/50478231 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货!

前言:

MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注,但在项目开发中选择一种这样的软件设计模式需保持慎重心态,一旦确定 使用MVP作为你App的开发模式那么你就最好坚持做下去,如果在使用MVP模式开发过程中发现问题而且坑越来越大,这时你想用MVC等来重新设计的话基 本上就等于推倒重来了。

要知道在Android上MVP在现在为止并没有统一的标准或者框架,不像SSH这三个成熟稳重强而有力的三剑客支持推动着 Java EE的开发,所以在运用MVP时一定要做好自己的理解,并且尽量预知自己App各模块的需求(客户说改改改,我们就改改改 :-( )以便提前做好充分的设计工作。

当然MVP既然能出现那么必然有它的优点的,不然谁会理会这个冒出来的东西,下面就对Android中MVP做一些阐述。

MVP与MVC简介

MVC:

一个模型可以对于多种视图模型,比如一批统计数据你可以分别用柱状图、饼图来表示。

  • M-Model-模型。JavaBean实体类,用于保存实例数据
  • V-View-视图 。程序的UI界面,用于向用户展示数据以及接收用户的输入。(在Android中体现为Activity)
  • C-Controller-控制器 。(在Android中体现为Activity)

MVP:

  • M-Model-模型。JavaBean实体类,用于保存实例数据。负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
  • V-View-视图。负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
  • P-Presenter-表示器。 作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。

从MVC和MVP两者结合来看,Controlller/Presenter在MVC/MVP中都起着逻辑控制处理的角色,起着控制各业务流程的作用。

而 MVP与MVC最不同的一点是M与V是不直接关联的也是就Model与View不存在直接关系,这两者之间间隔着的是Presenter层,其负责调控 View与Model之间的间接交互,MVP的结构图如下所示,对于这个图理解即可而不必限于其中的条条框框,在不同的场景下多少会有些出入的。

此外Presenter与View、Model的交互使用接口定义交互操作可以进一步达到松耦合也可以通过接口更加方便地进行单元测试。

这里写图片描述(原文中不是这张图片,我觉得原文中的图片描述不正确)

MVP之Model

模型这一层之中做的工作程序中各种数据的处理,复杂一些的就明显需要实现一个Interface来松耦合了。——怎么做

MVP之View

视图层很轻薄,负责显示数据、提供友好界面跟用户交互就行。MVP下Activity和Fragment体现在了这一 层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。

  • Activity上滚动列表时隐藏或者显示Acionbar(Toolbar),这样的UI逻辑时也应该在这一层。

  • 在View上输入的数据做简单判断

    • 例如:EditText的输入数据,假如是简单的非空判断则可以作为View层的逻辑
  • 在View上输入的数据做复杂判断

    • 例如:从数据库获取本地数据进行判断时明显需要经过Model层才能返回,所以这些细节需要自己掂量。

MVP之Presenter

Presenter层处理复杂的逻辑、程序各种逻辑分发。收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。——做什么

MVP的优点:

1、Activity 代码变得更加简洁

在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它 的首要职责是加载应用的布局和初始化用户界面,并接受并处理来自用户的操作请求,进而作出响应。

问题:
在MVC中,随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。

解决:
将其中复杂的逻辑处理移至另外的一个类(Presneter)中时,Activity其实就是MVP模式中 View,由此人们在MVC的基础上演化出了MVP

在 Android中很重要的一点就是对UI的操作基本上需要异步进行也就是在MainThread中才能操作UI,所以对View与Model的切断分离是 合理的。

MVP优点:

  • 基本上activity中只有FindView、SetListener以及Init的代码。对Presenter的调用,对View接口的实现。
  • 只要看Presenter的接口,就能明白这个模块都有哪些业务,能快速定位到具体代码。
  • Activity更容易看懂,容易维护,以后要调整业务、删减功能也就变得简单许多。

2、方便进行单元测试

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

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


3、避免 Activity 的内存泄露

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

解决:
把业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM(原作者认为的MVC中的Controller层是在Activity中实现的,所以认为MVP可以避免Activity的内存泄露)参考

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

几篇博客对同一概念理解的异同:

MVC中的V

我认为是activity

MVP中的M

M负责业务逻辑和数据的管理,P负责逻辑的分发:


P负责业务逻辑,M负责数据的管理:


  • 我认为是P负责宏观上业务逻辑——做什么(业务逻辑的分发,对View事件的处理等)
  • M负责数据的一些操作——怎么做(也可以认为是微观上的业务逻辑,处理数据,例如:对数据判断,进行比较,然后返回给p)

由于MVP是从MVC中演化而来的,之所以会诞生MVP的原因可以查看MVP的优点,所以我认为两种模式中M应该都是数据处理,这篇文章中的下面句话,可以更好理解M是负责数据的管理的

“MVC (Model-View-Controller):M是指逻辑模型,V是指视图模型,C则是控制器。一个逻辑模型可以对于多种视图模型,比如一批统计数据你可以分别用柱状图、饼图来表示。”

另类用法:

由于是人们宏观意识的一种模型,没法论证绝对正确,所以存在不同的声音,以下为原作者的想法,我认为正确的做法还是上面描述的那样

这篇文章中,他认为

Activity和Fragment要作为presenters

使用Activity和Fragment作为视图层(View)真的合适么?

目前很多使用了MVP模式的android 项目,基本上都是将activity和fragment作为视图层来进行处理的.而presenters通常是通过继承自被视图层实例化或者注入的对象来得到的. 诚然,我同意说,这种方式可以节省掉很多让人厌烦的”import android..”语句, 并且将presenters从activity的生命周期中分割出来以后, 项目后续的维护会变得简便很多.这种思路是正确的, 但是,从另一个角度来说, activity 有一个很复杂的生命周期(fragment的生命周期可能会更复杂), 而这些生命周期很有可能对你项目的业务逻辑有非常重大的影响. Activity 可以获取上下文环境和多种android系统服务. Activity中发送Intent,启动Service和执行FragmentTransisitons等。而这些特性在我看来绝不应该是视图层应该涉及的领域(视图的功能就是现实数据和从用户那里获取输入数据,在理想的情况下,视图应该避免业务逻辑).

基于上述的原因,我对目前的主流做法并不赞同,所以我在尝试使用Activity和Fragment作为Presenters。

参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0227/2503.html原文中有demo
http://segmentfault.com/a/1190000003927200原文中有demo
http://www.cnblogs.com/devinzhang/archive/2012/01/26/2329869.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛瑄

文章不错,请博主吃包辣条

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值