安卓开发中的Model-View-Presenter(MVP模式)

在软件开发行业中找到一个Android开发的架构标准是相当复杂的。确实,在一段时间内,一个非常基础的MVP已经被提出来打破 God-Object (完全负责所有的事情),而且,就在不久之前,谷歌提出的MVVM,使用它的体系结构组件,正在被采用(ViewModel, LiveData, LifeCycleObserver…)。尽管这些体系结构(尤其是MVVM)实现了分离组件并使其可测试和可重用的目的,但我们仍然发现了一些问题,使我们自问这是否是我们可以使用的最佳体系结构。

在第一种情况下,view和Presenter,以及presenter 和 mode都是互相需要知道的。对于MVVM,虽然ViewModel不知道View,但是View知道ViewModel,这使得重用具有不同ViewModel的视图变得复杂。依赖项投资原则(DIP)只在一个方向得到了解(视图=>服务,而不是服务=>视图)。这个问题是存在的,因为两个方向上的依赖关系的给了我们更大的内聚性和更少的耦合,但也增加了复杂性。这取决于读者来决定这种取舍是否值得。

对于层之间的通信,在经典的MVP案例中,我们发现它是通过回调完成的(这将最终把我们的应用程序变成回调地狱),而在MVVM LiveData中使用,虽然它允许我们避免回调,但它没有为我们提供大量的操作符来操作数据(在编写本文时,我们只有map和switchmap)。

这些是促使我们在编写应用程序时尝试找到更好解决方案的主要原因。

纯MVP和无controller架构(Pure Model-View-Presenter or Controlerless Architecture)

在我们的例子中,我们选择了一个叫做纯MVP的体系结构(我们通常也将其称为无控制器的架构),它允许我们完全分离模型层的视图。多亏了Presenter 层,它的唯一功能是将单个视图与单个应用程序服务(也称为interactor,或用例)连接起来;因此,为了构建一个屏幕,我们可以使用N个演示者,每个视图服务对一个。

为了说明我在本文中解释的内容,参考GitHub上一个小的示例/项目(纯模型-视图-演示者):Pure MVP in GitHub.。

因此,我们可以将视图和服务理解为发出事件和接收信息的黑盒(通过输入和输出“电缆”),我们的Presenter 将负责将组件的输入电缆连接到另一个组件的输出电缆,反之亦然。

此外,使用lambdas用于视图与服务通信,使我们能够避免直接暴露这些组件之间的可观数据。像这样,我们可以使用RxJava在我们的服务,所以我们可以操作数据与我们所有这个库提供的运营商和LiveData视图的一部分,这将使我们能够使一个实现,意识到我们的活动的生命周期的变化,甚至使用谷歌提供的视图模型。

View

在Android中,我们的视图的实现将对应于一个活动或一个片段(在示例/项目中是片段),但它可以是一个ViewModel,甚至是一个可视化组件。这里不讨论视图是由N个片段组成的活动的情况,因为每个片段都有M个演示者,我们可以假设视图是这些片段中的每一个,尽管它们随后被分组到一个片段中(甚至在另一个片段中)。

Service

我们的服务将负责应用所有业务逻辑并协调不同的域服务,或者直接负责向应用程序提供/存储信息的存储库。

Infrastructure Layer

在负责向应用程序提供数据或存储必要数据的层(网关、BD、共享首选项、缓存…)。每个通信通道都将使用存储库模式实现,并将其注入到需要它们的服务中。

好处是什么?

正是由于使依赖服务=>视图反转,而且不仅依赖视图=>服务,我们还可以做以下事情:

  • 在运行时视图中添加/删除更多侦听器
  • 时使用多个“侦听器”的相同视图。例如,在单击按钮时,我们必须与服务器通信并启动跟踪事件。
  • 通过调试我们的应用程序,我们可以在单个站点中看到演示者,所有事件流。
  • 为了能够在视图和服务组件之前应用“演示者优先”设计,定义这两个接口,例如方法和事件

测试

在为我们的应用程序编写测试时,重要的是我们可以测试独立的代码单元,这些代码单元在应用程序的其他部分没有副作用,它们的依赖关系可以被模仿(这些代码单元不依赖于应用程序的其他部分)。由于在这个体系结构中,我们的组件是接收事件和发出信息的黑盒,因此很容易验证在接收X事件时发出了信息Y。

基础架构层(数据)也很容易测试,因为我们所要做的就是模拟服务器的响应,为此,我们将使用来自OkHttp的MockWebServer。

发展方向?

目前,有一些体系结构,如Redux和Redux-saga,在依赖项投资的原则下工作,在某种意义上说,它们完全是事件驱动的。观察前端架构的演变,认为Android正在接近一个类似Redux的架构并不是不合理的。

改进

有许多事情可以改进,例如:

  • ViewModel: 可以在视图和表示器之间添加一个额外的层,表示器负责保存视图的状态。此外,这个视图模型可以直接将数据绑定注入到XML中,并使用LiveData将可视化组件绑定到LiveData的可观察对象。另外,在我们必须处理适配器时,研究如何实现这种绑定也是我们目前正在研究的一个挑战。
  • Authentication: Github API有一个限制,如果不验证用户,相同的IP不能执行超过一定数量的调用(https://api.github.com/rate_limit);因此,通过Github网站添加一个使用OAuth2进行基本身份验证可以改进这个应用程序
  • Pagination: 目前还没有实现分页机制,因此应用程序不会显示超过一定数量的搜索结果,因此在这种体系结构中实现分页机制可能是一个有趣的挑战。

请关注公众号:程序你好

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-08-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏写代码的海盗

Nodejs课堂笔记—第一课:修改Webstorm的默认主题

    最近小半年一直在忙于研究Docker源码,也在写相关的分析文章。但受限于某些条件不能发布到网上,甚为郁闷。而最近几天,接到新的开发任务,需要使用node...

27850
来自专栏owent

libcopp(v2) vs goroutine性能测试

本来是没想写这个对比。无奈之前和call_in_stack的作者聊了一阵,发现了一些libcopp的改进空间。然后顺便看了新的boost.context的cc部...

10910
来自专栏IT大咖说

一位前端专家构建GraphQL工程的心路历程

内容来源:2018 年 6 月 9 日,国内某大型电商公司用户体验部门前端开发专家邓若奇在“杭州第一届 GraphQLParty—GraphQL与领域驱动带来的...

1K10
来自专栏美团技术团队

美团点评前端无痕埋点实践

构建一个数据平台,大体上包括数据采集、数据上报、数据存储、数据计算以及数据可视化展示等几个重要的环节。其中,数据采集与上报是整个流程中重要的一环,只有确保前端数...

1.1K60
来自专栏Android开发实战

腾讯最热门30款开源项目

开源是个好东西,马化腾除了王者荣耀还是干了些好事情的。腾讯最近开源的一些比较热门的项目,可以学习了解下哈

1.1K30
来自专栏SDNLAB

分层安全用于通用客户端设备(uCPE)部署的准则

15450
来自专栏腾讯Bugly的专栏

《iOS APP 性能检测》

| 导语 最近组里在做性能优化,既然要优化,就首先要有指标来描述性能水平,并且可以检测到这些指标,通过指标值的变化来看优化效果,于是笔者调研了iOS APP性能...

1.8K50
来自专栏腾讯NEXT学位

webpack 4 测试版 —— 现在让我们先一睹为快吧!

37750
来自专栏前端架构

批量删除腾讯专栏文章的脚本

批量删除腾讯专栏文章的脚本,腾讯云专栏签约后,抓取文章不插入原来连接,这个我怎么评价了呢!只好删除,走人了

38030
来自专栏美团技术团队

iOS App冷启动治理:来自美团外卖的实践

冷启动时长是App性能的重要指标,作为用户体验的第一道“门”,直接决定着用户对App的第一印象。美团外卖iOS客户端从2013年11月开始,历经几十个版本的迭代...

20220

扫码关注云+社区

领取腾讯云代金券