Android开发MVP模式--项目实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dfskhgalshgkajghljgh/article/details/79050421

1 前言

苏宁+App是苏宁易购集团零售云研发中心分销研发中心主要产品之一,由于项目处于初期阶段,业务逻辑复杂,导致业务需求变动快,常常在开发甚至测试过程中出现界面或者后台接口调整的情况。
App客户端如何在外部需求不断变化的情况下,降低模块耦合,尽可能减少每次代码修改量,一方面减少开发人员的工作量,另一方面降低测试工程师的工作量,最终顺利完成项目迭代开发。

2 为什么使用MVP模式

相信在2014年之前,绝大部分人开发Android应用,都是使用的MVC模式,M跟V一般没有什么问题,Controller层也就是对应Activity类,它的首要职责是加载应用的布局和初始化用户界面,并接受和处理来自用户的操作请求,进而作出响应。
随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿,打开以前项目的Activity,超过2000行的不在少数。
另外,由于项目的特殊性,互联网产品讲究速度,尤其是新产品,上线的时间会决定你在市场上的占有量。
App的理想情况是UED做好视觉稿,后台接口准备完毕,客户端同学一边做页面一边调试接口,做完自测后顺利交付测试。但是,理想很丰满,现实很骨感。
实际情况是,我们开始coding的时候,只有一份接口文档跟交互图。我们需要思考的是,我们必须把界面和接口数据解耦,接口联调和测试工作不能依赖界面的完成,当完成业务层代码后,就可以测试业务功能。基于上面的背景,我们选择了MVP模式。

3 什么是MVP模式

我们上面说的MVP架构,是Google开源的一个设计模式,主要是为了细分视图(View)与模型(Model)的功能,让View只做两件事:
 完成用户的交互;
 显示界面布局,同时让Model做数据的处理,业务逻辑放到另外的一个类(Presenter)中。
下面做具体分析:
 M:M层,在项目中负责数据的处理,包括本地数据库查询,网络数据获取都在这一层中完成。
 View:V层,在项目中是UI模块,也就是各种activity/fragment,负责绘制UI元素、与用户进行交互。
 P:P层,在项目做为View与Model的桥梁,M跟V层不直接交互,M层在获取到数据之后,传递到P,P层再通过接口回调到View层,同样,View层的点击等事件,通过P层去通知M层去处理。
如下图所示:
这里写图片描述

4 MVP模式应用实战

4.1苏宁+app项目结构图:
这里写图片描述
目前App整体项目架构如上图所示,各个层次的介绍如下:
 【前端界面层】:界面相关布局,如各种activity/fragment类。
 【业务逻辑层】:业务逻辑相关,如各种presenter类。
 【数据层】:数据相关,包括数据存储,获取,如各种model类。
 【运行服务层】:伴随应用生命周期自动初始化,自动销毁,提供一系列服务给其他业务模块调用,如各种service类。
 【业务框架层】:针对当前app跟业务有耦合度的公共方法,组件抽取。
 【基础框架层】:跟业务无关的底层组件,可以给多个app同时使用。
 【系统层】:android系统底层。
通过上面的架构图可以很直观的看出,我们日常业务功能迭代的时候,主要修改或者新增的代码都在前面三层,这里主要讲前面三层的使用规范。

4.2目录结构 :
下图为使用MVP模式时,购物车确认订单页面的目录结构:
这里写图片描述
model————————————————————————————数据处理
presenter——————————————————————————–业务处理
task————————————————————————————–网络请求
ui—————————————————————————————–页面
util—————————————————————————————当前模块公共类
view————————————————————————————–页面刷新回调接口

4.3总体逻辑设计
如图为购物车2界面,下面将围绕该界面来讲解如何用MVP实现具体业务功能。
这里写图片描述
为了更加直观看到MVP在当前业务中的使用,我们画了类图跟时序图,通过类图我们可以清楚类的设计,如下所示:
这里写图片描述
通过下面的时序图,我们可以很清楚的看到调用关系:
这里写图片描述
通过上面两张图,我们可以看到MVP在当前业务中对应的角色以及调用关系,下面深入代码层面继续讲解。

4.代码实现

1)M层(model)项目中很多网络请求是重复的,比如很多页面都会用到店铺信息接口,如果每个页面都要在不同model写一遍,那么复用性很弱。
所以跟Google在Github发布的mvpdemo不同,我们项目中每个网络接口都单独写成一个Task,以确认订单页面为例:model层定义模型抽象类(PSCShopCart2DataSource ),然后具体实现类(PSCShopCart2Repository )里面调用Task,发送网络请求。如下:
这里写图片描述
这里写图片描述

2)IView MVP模式中,M层跟V层不能直接通信,数据是通过presenter层接口回调到V层中。一般情况下,IView里面的接口就对应V层的功能。
这边会有人觉得特别复杂的场景会出现很多接口的情况,当然如果真出现这种情况,该合并的接口还是要合并,到activity中做简单的处理也是可以的,实际开发中一定不能被框架限制,不管什么模式都是为了业务正常迭代。
代码如下:
这里写图片描述
这里写图片描述

3)P层(presenter)原先杂糅在activity/fragment里面的业务逻辑移到presenter中,同时presenter做为M和V之间交互的桥梁。
由于activity跟fragment生命周期不同,会影响一些弹出框关闭的时机,所以项目中,activity跟fragment分别定义了一套基础业务抽象类,这边以activity基础业务抽象类来演示,所有的activity中用到的presenter都继承PSCBaseActivityPresenter:
这里写图片描述
PSCActivityNetTask主要做网络任务监听并回调到presenter中,还会设置生命周期监听,用于显示加载框。
这里写图片描述
presenter接受到网络回调后,根据接口返回的数据做业务处理,成功或者失败分别通过接口回调到View层,刷新界面。
这里写图片描述
这里写图片描述

4)V层(view)相信大多数App都会有baseActivity作为基类,将Activity公共部分抽取出来进行封装。
苏宁的基类叫做SuningActivity/SuningFragment,每个界面都需要把view跟presenter绑定/解绑,这些都可以放到基类中,然后定义protected abstract T createPresenter();将创建Presenter步骤交给子类实现。
代码量比较大,这边做了删减,仅保留MVP相关的代码,如下:
这里写图片描述
activity实现上面定义的IView,实现数据的接收,同时会在当前类中创建presenter,通过presenter方法调用model中的网络请求。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

5 总结

以上内容就是我们对于MVP架构的理解,并在苏宁+项目中实战后分享给大家。
MVC,MVP,MVVM不管何种模式,都可以实现功能,选择相应模式的时候,要看相对于目前业务来说的,何种模式能够封装变化,让各模块解耦,实现独立变化,减少日后的维护工作和暗藏的风险。
当然我们也不能陷入模式的陷阱,为了使用模式而去套模式。没有好的框架,只有适合的框架,如果大家发现我们当前项目中对于MVP的使用不对或者不完善的地方,欢迎提出来,我们一起探讨。

扫描二维码关注公众号,回复: 2922223 查看本文章

注:
原文地址51CTO.com:(http://developer.51cto.com/art/201711/559384.htm)


如有错误欢迎指出来,一起学习。

交流讨论群
群号:469890293

猜你喜欢

转载自blog.csdn.net/dfskhgalshgkajghljgh/article/details/79050421