Android MVP 解析+ 样例展示

来源:互联网 发布:淘宝开店成功案例 编辑:程序博客网 时间:2024/06/14 05:25

       看了一些介绍Android MVP的文章,结合自己的理解,整理MVP相关知识,以便复习和改进。

一、MVP介绍

      上来先看张图,这张图肯定很多文章都已经贴过了,不过因为它比较清晰的介绍了MVP和MVC的差异,所以借用一下

      



       从图中可以看出,MVP和MVC的明显区别就是,在MVC中,Activity会经常扮演着Controller的角色,同时又负责View的处理逻辑,常常导致一个Activity过于厚重,随着功能的增多,容易造成代码维护成本增加,而在MVP中,Model层只与Presenter层进行交互,Presenter只与View层进行交互,这里的View可以是Acitivity或者Fragment,具体两种可以在下面的示例中体现,MVP模式将Activity或Fragment从Controller(MVC)中分离出来,他们只需要负责View层的展示工作,让业务处理逻辑交给Presenter处理,这样的模式耦合度低,在可维护性和可扩展性上都具有良好提升。

二、样例分析

OK,上面只是比较抽象地介绍了一下MVP模式,那么接下来从例子的角度出发,看一下在实际应用中如何使用MVP模式进行开发。


假设我们接到了一个需求,比如说开发一个登录界面,UI给我们的界面是这样子的(尴尬可能图片看起来丑,但是为了简化讲解内容,提取核心思想,就稍微将就一下吧。):


那么这个需求对应到MVP三个模块中又需要设计哪些东西呢。


结合上图,我们需要知道发起登录这个操作在MVP三层中的传递机制是怎么样的,首先用户通过在View层点击按钮出发登录请求,并将需要的数据(用户名+密码)发送给Presenter,Presenter将数据发送给Model,Model经过某种方式验证输入数据的正确性,并激发presenter的某个回调函数,最后 presenter在回调函数中调用View的函数更新界面状态。


先考虑View层,界面上有两个EditText作为输入,有两个Button作为Event触发器,那么我们需要设计‘View Function Interface’(出自沃兹 基说得),我这里把它叫做界面功能函数,对于UserName和Password,我们需要getUserName()和getPassword()两个ViewFunction为user event(也就是用户点击login按钮)传递数据,这是主要接口,还有其他辅助接口,比如说为了用户体验,设计showProgress()和hideProgress()来应对耗时操作时的提醒,当然也可以为了显示良好,在用户输入信息错误或者正确的时候给予提示,设计接口showErrorToast()和showCorrectToast()。因此对于View层我们需要设计如下接口:


然后,我们设计Presenter,Presenter层主要负责业务逻辑,例如登录逻辑,所以设计接口login(String userName, String password),而同时为了完成与View层的交互,需要持有View的引用,所以还需要接口setILogView(ILoginView view),当然也可以改变接口login(String userName, String password, ILoginView view),还可以在构造函数中完成依赖,本例采用构造函数完成依赖。

同时,为了响应登录处理后的情况,需要设计lOnLoginListener,用于Model处理完成后,通知Presenter完成情况。

然后就是model层设计,Model需要处理登录请求的逻辑,所以设计LoginModel:

从接口角度看整体流程如下:


工程结构:


这样就完成了MVP模式下的一次事件调用流程,实现代码在文末贴出github地址。

郑重提示,本文提出的实例主要是为了讲解MVP在实际中应该如何映射,工程结构就我个人而言比较倾向于Google Samples中提出的MVP实例代码,它里面是按照功能块划分包结构,有兴趣的可以去看看。GoogleSamples地址:https://github.com/googlesamples/android-architecture/tree/todo-mvp

文中实例地址:https://github.com/ProfJerry/Android-MVPDemo



QA:

1.Model不是数据模型吗?为什么还有处理业务逻辑的功能呢?

A:model层根据不同的情况定义。有时候可能就是单纯的数据。有时候可能是包含了对数据的存储以及逻辑运算。

2.为什么需要LoginModel接口,而不是直接写一个实现类LoginModelImpl?

A:方便实现多态,还可以方便单元测试和接口模拟操作

3.Adapter位于哪一层?

A:个人认为是View层,因为Adapter实际上是和界面绑定的,它主要是ListView的DataSource和Delegate,获取数据的业务逻辑可以交给Presenter去写,Adapter主要还是获取数据以后的数据呈现方面。