Android MVP 架构学习(二)

之前的文章对 MVP 模式进行了简要的介绍,本文则深入探讨 MVP 的组成和实现。 前置文章:Android MVP 架构学习(一)

组成分析

blueprint.png

表示数据模型以及业务逻辑的类的统称。但是,必须注意 Model 层的类并不只是实现数据表、Bean 等,它应该把一切数据获取、处理、规格化等行为细节封装好,然后提供给 Presenter。 为了解耦 Model 和 Presenter 可以设计一组数据接口,方便 Presenter 访问比如 MVP Blueprint 图片中的 DataManager。而很多时候 DataManager 也不会直接操作底层的数据访问类,而是通过接口访问它们,比如:访问数据库的 DbHelper、访问 Shared Preferences 的 PreferenceHelper 和 访问 Restful API 的 ApiHelper。毕竟,Android 系统中数据操作方面的方法繁多,优秀的第三方库层出不穷,甚至系统提供的 API 都会不断改进,设计一系列的 Helper 接口屏蔽底层实现仍是很有必要的。

详细的理解 Model 层主要负责有:

  • 从网络、数据库、文件、传感器、第三方等数据源读写数据
  • 对外部的数据类型进行解析转换为 app 内部数据交由 Presenter 处理
  • 对数据的临时存储,管理,协调上层数据请求

UI 表现层,在 Android 中就是 Activity,以及与 Activity 相关的 XML 文件、Fragment、自定义 View。但是,应注意 View 自身不应该包含 UI 逻辑,即不能自己更新 UI 元素,而由 Presenter 控制进行 UI 更新。

详细的说,View 负责:

  • 提供UI交互
  • 在presenter的控制下修改UI
  • 将业务事件交由presenter处理

一般情况下,MVP 的模式为 Passive View 模式,View 和 Model 没有任何交互,必须通过 Presenter 进行。也由 Supervising Controller 模式,类似 MVC 模式,View 和 Model 可以通过数据绑定的方式进行交互。

Android 中尤其要注意设计一组 View 层接口给 Presenter 访问,解耦 View 与 Presenter,防止重蹈原有 MVC 模式的失败,比如 MVP Blueprint 图片中的 MvpView。

连接 View 与 Model 的中间层,也是负责所有 UI 逻辑和部分业务逻辑的逻辑层。Presenter 层的成员应该是纯粹的 Java 类,不应该访问 Android 系统提供的 API。

详细描述 Presenter 职责为:

  • 接收 View 传递的用户交互数据
  • 按照 UI 逻辑决定如何更新 UI
  • 按照业务逻辑决定获取或更新 Model 层对象

要在 Activity 中连接 View 层和 Presenter 层,一般一个 Presenter 和一个 View 对应,如果 View 较复杂则可对应多个 Presenter。 Presenter 层实现接口方便 View 访问,比如 MVP Blueprint 中的 MvpPresenter。

具体来说各个层的类和接口实际不难定义,但是它们的连接机制则不是那么清楚,各个组件之间的通信原则有:

  • Application 类通过依赖注入方式实例化 Model 中的 Helper 类示例以及 AppDataManger 类实例(注意必须赋值给接口类型)
  • View 只能通过 MvpPresenter 接口访问 Presenter
  • Presenter 只能通过 MvpView 访问 View,只能使用 DataManager 访问 Model
  • AppDataManager 实例应该是单例,其他 Helper 类如有必要也应为单例

优点与缺点

  • 降低耦合度,实现了 Model 和 View 真正的完全分离,方便修改 View 和 更好 Model 实现
  • 模块职责划分明显,层次清晰,易于阅读和维护
  • 方便测试,因为 Presenter 不涉及 Android 系统 API,尤其利于业务逻辑测试:可以通过 Mock 一个实现接口的 View 对象。然后依赖注入到 Presenter 中,单元测试的时候就可以完整的测试 Presenter 应用逻辑的正确性
  • View 可复用:View 与业务无关,只与 UI 相关,只要实现了相应接口就能轻松复用
  • Presenter中除了应用逻辑以外,还有大量的转接 View -> Model 和 Model -> View 的手动同步逻辑,造成Presenter比较笨重,维护起来会比较困难
  • UI 逻辑放在了 Presenter 中,所以 View 和 Presenter 的交互会过于频繁
  • 随着代码增长 Presenter 极易过于深入地控制 View,让耦合度慢慢增加
  • 额外的代码复杂度及学习成本

参考文章

Essential Guide For Designing Your Android App Architecture: MVP: Part 1

Android App的设计架构:MVC,MVP,MVVM与架构经验谈

Android MVP 详解(上)