MVP for Android: How to organize presentation layer

Android MVP:如何组织表示层

FROM: http://antonioleiva.com/mvp-android/
AUTHRO: Antonio Leiva

MVP(模型 视图 表示器)模型是从知名的 MVC(模型 视图 控制器)模式演变而来的,当前在 Android 开发领域越来越重要。有越来越多的人开始讨论它,但是很难找到可信的、经过良好组织的信息。这就是为什么我想通过这篇博客鼓励大家来进行讨论,并将我们所知道的知识以最佳的方式应用到我们的项目中。

什么是 MVP?

因为MVP模式让表示层从业务逻辑中分离出来,所以接口怎样工作与怎样进行展现分离开。理想情况下,MVP模式能够实现同一个业务逻辑能够有完全不同的可交互视图。

首先需要说明的一点是 MVP 并不是一种架构模式,它仅负责处理表示层。通常情况下,在架构中采用该模型比使用要好。

为什么使用 MVP?

Android开发中我们会面对这样一个问题,它由这样一个事实导致:Android 的 Activity 将接口和数据访问机制紧密耦合在一起。比如 CursorAdapter 就是一个典型例子,它既作为视图的一部分,同时带有游标,而游标又与数据访问层有紧密联系。

对于一个对扩展性和可维护性有要求的应用,我们需要定义良好的分层。比如,如果我们不再从另外一个数据库中取回数据,而是需要从 Web 服务中获取数据,我们应该怎么办呢? 难道我们得重新实现全部视图吗?

MVP模式让视图从数据源中独立出来。通过使用 MVP 模式,我们将应用程序至少划分为三个层次,通过划分层次,我们可以独立地对每个层次进行测试。通过使用 MVP 模式,我们就能将大部分的业务逻辑从 Activity 从抽取,这样,我们不用 Instrumentation 测试也能对业务逻辑进行测试了。

如何在Android开发中实现MVP?

实际上,和其他许多模式一样,MVP模式也有许多变体,因为每个人都按照自己的需要对模式进行调整。通常情况下,MVP模式根据我们代理给表示器的职责的程度来划分类别。

启用或禁用视图滚动条应该是视图的职责还是表示器的职责?动作栏中应该显示哪些动作,这是视图的职责还是表示器的职责?这类决定都比较难以抉择。虽然下面会介绍我是如何进行抉择的,但是我更鼓励这篇博客称为一个让大家能够讨论的地方,通过大家的讨论来决定应用MVP模式的规则,因为到目前为止并没有一种标准来供大家参考。

表示器

表示器的职责是担当视图和模型的中间人。表示器从模型中取回数据,然后将数据返回给视图,如果需要,还对数据进行格式化以符合视图展示的需要。虽然都是视图与模型的中间人,但是典型的 MVC 模式不同,MVP 中的表示器同时还决定视用户与视图交互时应该发生什么。

视图

视图,通常由Activity实现(也可能是 Fragment 或者 View,这要根据你的应用的组织方式而定),包含着对表示器的引用。为视图提供表示器的理想方式是通过依赖注入实现,比如通过使用依赖管理库 Dagger;不过如果不通过依赖注入,视图就得自己创建表示器对象。视图唯一的职责就是,在有交互动作时(比如点击),调用表示器中的方法。

模型

在一个良好分层的应用中,模型仅仅作为领域层和业务逻辑层的接口。如果使用Bob大叔的”clean architectrue”,模型可能会作为一个实现用例的 interactor(参考:clean architecture)。关于该话题我想在以后的文章中再展开。现在,只需要将模型看做我们想要显示在视图中的数据的提供者就可以啦。

示例

因为要通过文字进行解释的话,可能会篇幅会比较长,所以我在 Github 上创建了一个 MVP 示例。其中包含了一个登陆界面,登陆界面会会用户输入的数据进行验证,通过验证后允许访问主页,主页中是一个列表,列表中的列表项的数据是从模型中获取的。这篇文章并不会对代码进行说明,因为代码示例实际上并不复杂。但是如果你觉得代码比较难以理解的话,我会写一篇博客来解释。

查看示例

结论

在Android中将接口从逻辑中分离出来并不容易,但是通过使用模型-视图-表示器模式,在防止Activity最终变成包含上百行或上千行的代码构成的耦合度非常高的类时,还是很有帮助的。而且,在大型应用中,它还能让我们的代码组织的更好。如果不使用的话,可能代码会非常难以维护和扩展。

你可能感兴趣的:(android,mvp)