Android MVP 架构学习(二)
之前的文章对 MVP 模式进行了简要的介绍,本文则深入探讨 MVP 的组成和实现。 前置文章:Android MVP 架构学习(一)
组成分析
Model
表示数据模型以及业务逻辑的类的统称。但是,必须注意 Model 层的类并不只是实现数据表、Bean 等,它应该把一切数据获取、处理、规格化等行为细节封装好,然后提供给 Presenter。 为了解耦 Model 和 Presenter 可以设计一组数据接口,方便 Presenter 访问比如 MVP Blueprint 图片中的 DataManager。而很多时候 DataManager 也不会直接操作底层的数据访问类,而是通过接口访问它们,比如:访问数据库的 DbHelper、访问 Shared Preferences 的 PreferenceHelper 和 访问 Restful API 的 ApiHelper。毕竟,Android 系统中数据操作方面的方法繁多,优秀的第三方库层出不穷,甚至系统提供的 API 都会不断改进,设计一系列的 Helper 接口屏蔽底层实现仍是很有必要的。
详细的理解 Model 层主要负责有:
- 从网络、数据库、文件、传感器、第三方等数据源读写数据
- 对外部的数据类型进行解析转换为 app 内部数据交由 Presenter 处理
- 对数据的临时存储,管理,协调上层数据请求
View
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。
Presenter
连接 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