Android当中的MVP模式(七)终篇---关于对MVP模式中代码臃肿问题的思考

摘要:在学习 MVP 模式的过程当中,见到很多文章都提到一句话:「使用 MVP 模式引入了 Presenter 层,这样可以将 View 层和 Model 层解耦,但是项目的代码量会大大增加,不过这个牺牲是值得的。」但是这个如果不做处理的话,随着项目体量的扩大,项目当中会充斥着很多相同逻辑的代码,是在是不能忍,通过前面几章的封装可以缓解这个情况,但是还剩下一个问题是目前解决不了的,那就是 Presenter 的管理问题和 View 层无关代码问题,这一篇就针对这两个问题记录一下思路。

学习 MVP 模式的过程中引发的一些思考

最近一个月都在学习 MVP 模式,自己也动手做了几个小 Demo,由于 Demo 规模不大,所以代码臃肿的问题没有很好的反映出来,不过却是反应出来了其他的问题。比如当我需要实现另外一个需求的时候,我需要去重新创建 M V P 三层的代码,而这三层的代码很多逻辑都是相似的,比如说 Model 层就是去访问服务器端请求数据,然后将数据回调到 Presenter 层,只是访问的服务器端 URL 地址不同,返回的数据不同,这个差异性通过对网络请求工具做封装,并且封装 Model 层相同逻辑代码,可以很好的解决;再比如说 View 层会涉及到很多 UI 界面的刷新问题,常用的 ProgressBarToast ,显示错误信息状态码等基本功能,也可以通过封装 BaseMvpActivityIBaseView 来解决,所以这就是前面六篇文章的由来。至于代码臃肿所体现出的问题,我总结为如下两个:

  • View 层中充斥这各种事件的分发和事件的注册,我们希望 View 层是这样的:只有 onXxxxZzzz() 形式的回调方法用于改变UI,比如: onLoadMessage(List<Message>) 回调在加载完 Message 之后来进行UI的更新,那么事件的注册和分发就需要到其他地方去处理。

  • View 层和 Prensenter 层接口的管理问题,比如当我们需要移植一个模块的时候,由于 View 层和 Presenter 是紧密相连的,所以这两层需要一同移植,不过可能由于项目体量的原因,PresenterView 的接口比较多,没办法一次性的移植,需要不断的测试。

英国计算机学家说过一句话:
All problems in computer science can be solved by another level of indirection.
翻译成中文就是:计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。

比如十分复杂的Internet国际互联网络中数据传输的问题,也是通过分层来决绝的,这可以体现在 TCP/IP 四层模型和 OSI 七层模型当中。

这么复杂的问题都可以引入中间层来解决,那么 MVP 中的问题就更不在话下了。

关于解决上述两个问题的思路

View 层臃肿问题解决思路

第一个问题,天天_byconan,大神的博客中有很好的解决思路,下图也是摘抄自他的博客。

先上两张图:

引入 PresenterProxy 层

  • 通过使用一个 Presenter 层代理的方式,在 PresenterProxy 中处理各种时间机制,View 中维护一个对 PresenterProxy 的引用,PresenterProxy 也实现了真实 Presenter 层的接口,这样就可以在 View 中通过代理调用真实的 Presenter 层对象。

引入 Controller 层

  • MVP 模式增加一层专门用于处理各种时间派发的 Controller 层,Controller 层的作用仅仅是用于处理事件,并根据事件通过维护的 Presenter 层对象派发到对应的业务当中去,也就是说 View 层只有一个 Controller 对象, View 层不会主动的去调用 Presenter 层对象,但是 Controller 层和 Presenter 层都可能回调到 View 层来刷新UI。

这两张图就为我们提供了很好的解决思路,虽然我还没有动手实践过,但是从思路上来说,是没有问题的。

Presenter 和 View 层接口管理问题解决思路

在笔者查看了大量的文章资料之后,发现这个问题 Google 已经给出了一个十分好的的解决思路,这个答案就在 官方的TODO-MVP Sample里,这个 Demo 通过用 MVP 模式实现了一个TODO应用,先贴一下这个应用在 Android Studio 中的代码分包情况:

整个 APP 等架构十分的清晰,不愧是出自 Google 大牛之手!!!

  • 管理接口的核心类是每一个模块当中的 XXXXContract 接口

  • 并且这个项目当中的 Model 层是它最大亮点, 上图中 data 包下就是它的 Model 层, TasksRepository 维护了两个数据源,一个是本地(SQLite 数据库),一个是远程(网络服务器),并且将不同的数据源抽象成为 TaskDataSource 接口,这种面向接口编程的思想,让我们很容易的修改数据源,或者是扩展数据源,这也是依赖倒置原则的体现。

放一下项目整体架构图:

出自:https://github.com/googlesamples/android-architecture/tree/todo-mvp/

接下来准备好好研究一下这个项目的架构和实现,并且这个 Google 的开源库是用不同的架构去实现相同的 APP,提供了很多架构的基本应用:clean dagger rxjava databinding 等,有空一定好好研究。

又立 Flag

  • MVP 模式也算是入门了吧,后面准备结合上面的 TODO-MVP 项目,在练练手,然后把上面提到的几个思路好好梳理一下,关于 TODO-MVP 项目也准备写一篇文章总结记录一下。

  • 关于 Retrofit 的使用我也看了好几篇文章,基本的使用应该是没问题的了,不过在这个过程中,感觉自己缺乏服务器端知识,什么 RESTful API ,什么 URL 的构成什么的,没有系统的了解过(对,就是写 Retrofit 的网络请求接口的时候,有点迷失了~),后面这一块要恶补一下。

  • 下一个就是 Dagger2 了, 关于 Dagger2 也看了几篇文章,感觉它的概念性的东西确实挺多的,上手不是太容易,不过也没关系,慢慢来。

共82.3k字
0%
.gt-container a{border-bottom: none;}