重新认识MVP

其实本人对于层出不穷的各种框架都是嗤之以鼻的态度,从实际经验来讲,各种框架对于一个普通的Android应用来说根本就是小题大做,当然了,如果说你的Android应用已经到了Google官方那几个应用的规模,那就另说了。

所以,如果你所在项目就是一个普通的规模的项目,就不要继续往下看了。

我也不擅长这些虚的东西,只是最近google官方除了一个demo项目,写了比较火的几种框架是具体怎么实现的,然后就花了一点时间看了下MVP的demo,给我最大的感触就是:国外这些大神真的是测试驱动开发,个人认为,他们搞出来这些框架很大程度上都是因为方便进行单元测试。

所以,如果你根本没有单元测试(事实上国内的大部分公司似乎都没有单元测试),那普通的开发模式MVC已经足够了。

OK,讲了这么多好像都是让大家不要用这些模式,下面讲讲这个模式是怎么实现的(我也就是根据google的demo来说的)。

demo的地址是:android-architecture,clone下来之后切到todo-mvp分支上即可。

【注意】在讲之前我们需要明白一点,这些模式很大程度上是基于接口的,就是说每层的交互都尽可能保证用接口来描述,而不是整个类。这个原则叫做依赖倒置。

M

首先是M层,这边的M层不仅仅是数据模型,而是整个数据源的概念,我们可以想想数据源有哪些?一个是内存数据(可能是图片的内存缓存,可能是内存中记录的安装包列表等等),一个是数据库或者sharedpreference或者content provider的数据来源,还有就是一般的网络请求的数据来源。

我们可以看到google的demo中有一个TasksDataSource接口,定义了有关Task的全部数据操作,然后有一个类叫做TasksRepository也就是数据源集合,这个数据源集合包含两种数据源:mTasksRemoteDataSourcemTasksLocalDataSource,这两数据源也是实现了TasksDataSource接口的。顾名思义,一个是本地的数据源(可以想象成我们的数据库数据),一个是远程的数据源(可以想象成网络数据),整个这种模式类似于策略模式……好吧,其实也不太像啦。就是很简单的,数据源集合的操作实际上分给了两个数据源去做的这种形式。具体数据来源是怎么来的就是mTasksRemoteDataSourcemTasksLocalDataSource做的事情了。

另外,返回数据的方式有几种,一种是数据源接口方法返回值,一种是接口参数传递一个回调方法,第一种是给内存数据用的,第二种是给异步用的。

到此M层做完。

V

V层也就是Activity和Fragment对应的UI,但是,我们不是把整个Activity或者Fragment拿出去交互的,而是接口,始终牢记上面一开始的注意点,要用接口描述。

我们可以看到TaskDetailFragment类,实现了一个接口TaskDetailContract.View,这个接口就是把UI层需要的操作抽象出来了。然后TaskDetailFragment拥有一个Presenter成员,这个Presenter在fragment初始化的时候就实例化了,fragment接收用户的输入,比如点击,然后就会把事件交给Presenter去处理。

咳咳,讲到这儿可能有个疑问,交给了Presenter处理,然后呢?我处理完了需要更新UI吧?如果遇到一点业务复杂一点的还需要处理一些自己的事情吧?OK,别着急,这就是P层做的事了。

P

P层做的事刚才讲了一点,就是处理一些程序中的逻辑性的事情和UI的,注意一点,业务相关的数据逻辑是M层的事情,只有程序上的一些细节才是给P做的。换句话说,P层只不过充当了MC之间的桥梁,把P层省略似乎也没什么问题。当然了,就像文中一开始说的,MVP全部省略也没什么问题……咳咳,本文不写也没问题……

打住,既然是MC之间的桥梁,那么Presenter类肯定需要有数据源和View的成员了,可以看到TaskDetailPresenter类中有mTasksRepositorymTaskDetailView,在TaskDetailFragment执行onResume的时候触发了TaskDetailPresenteropenTask(),这个方法显示执行M层的获取数据,获取回调之后就更新了V的UI。

至此P层结束。

框架图(流程)

没图。

我们根据刚才的流程总结一下: V <-> P <- M,V中的事件触发P的逻辑,P去获取M的数据,返回之后执行V的更新UI。好像写了半天的文章就这么一句话就完了。

写在最后

在google这个项目介绍中对于框架是这么说的,不管是哪种框架,都是根据你自己项目的大小,团队的水准,对于未来项目的可维护性等等各方面因素决定的。而这些,就不仅仅是Android开发技术能解决的,而真的是需要大量的项目经验和Leader的强大的管理能力。

写完手工~