Android 架构模式

Android 开发常用的架构模式有 MVC、MVP 和 MVVM,目的都是为了将业务和视图的实现代码分离,从而使同一个程序可以使用不同的表现形式。

MVC

MVC

  • Model:实体模型;
  • View:对应于 Activity、Fragment 和 xml,负责用户交互和数据展示;
  • Controllor:对应于 Activity 业务逻辑,数据处理;

数据流为:

  1. View 传送指令到 Controller;
  2. Controller 完成业务逻辑后,要求 Model 改变状态;
  3. Model 将新的数据发送到 View,反馈给用户;

_缺陷_:View 层和 Model 层是相互可知,耦合性大,像 Activity 或 Fragment 既在 Controller 层又在 View 层,造成工程的可扩展性可维护性非常差,承担的功能过多,自然代码量会增大。

MVP

MVP

  • Model:负责管理业务数据逻辑,如网络请求、数据库处理;
  • View:对应于 Activity、Fragment 和 xml,负责用户交互和数据展示;
  • Presenter:负责业务逻辑处理,完成 View 和 Model 间的交互;

MVP 模式将 MVC 模式中的 Controller 修改为了 Presenter,同时改变了通信方向,Model 层和 View 层不直接通信,由 Presenter 层中转,使得 View 和 Model 解耦。

MVP 数据流

  1. Presenter 和 View、Model 的通信是双向的;
  2. View 与 Model 不直接通信,通过 Presenter 传递;
  3. View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter 非常厚,所有逻辑都部署在那里;

MVP 把部分的逻辑的代码从 Fragment/Activity 中转移出来,在 Presenter 中持有 View 的引用,然后在 Presenter 中调用 View 暴露的接口对视图进行操作,这样有利于把视图操作和业务逻辑分开来。
MVP 能够让 Activity 成为真正的 View 而不是 View 和 Control 的合体,Activity 只做 UI 相关的事。

缺点:

  • 需要定义很多 Contract 协议接口和回调接口,不方便维护;
  • View 和 Presenter 是双向依赖的,一旦 View 层做出改变,相应地 Presenter 也需要做出调整。
  • 函数调用栈加深;
  • 复杂的业务同样会导致 Presenter 层太大,代码臃肿的问题。

MVVM

MVVM

  • Model: 负责管理业务数据逻辑。不仅包括实体类的定义,还需要对数据进行处理和读写。例如:使用 Retrofit 或 okHttp 进行网络请求,或数据库操作等;
  • View: 对应于 Activity、Fragment 和 xml,只负责 UI 相关的工作;
  • ViewModel: 负责业务逻辑处理,完成 View 与 Model 间的交互;

MVVM 的目标和思想 MVP 类似,利用数据绑定(Data Binding)、依赖属性(Dependency Property)、命令(Command)、路由事件(Routed Event) 等新特性,打造了一个更加灵活高效的架构。

MVVM 数据流

与 MVP 相比,View 和 Presenter 从双向依赖变成 View 可以向 ViewModel 发指令,但 ViewModel 不会直接向 View 回调,而是让 View 通过观察者模式去监听数据的变化,有效规避了 MVP 双向依赖的缺点。

数据流如下:

  1. View 中使用 DataBinding 的 Command 来绑定事件和响应事件,触发网络请求;
  2. ViewModel 进行分析处理,调用 Model 的数据请求方法;
  3. Model 将收到的请求参数等信息封装,调用网络请求库(Retrofit 等)与服务器进行交互;
  4. 服务器将 json 数据返回到 Model 层中,ViewModel 在回调中收到返回的实体类对象;
  5. View 通过 LiveData 观察数据,更新 UI。

DataBinding、ViewModel 和 LiveData 是 Android 中实现 MVVM 模式提供的架构组件,它们只是实现 MVVM 的工具。

  • Lifecycle: 生命周期状态回调;
  • LiveData: 可观察的数据存储类;
  • DataBinding: 可以自动同步 UI 和 data,不用再 findviewById();
  • ViewModel: 存储界面相关的数据,这些数据不会在手机旋转等配置改变时丢失。

缺点:

  • 多数据流: View 与 ViewModel 的交互分散,缺少唯一修改源,不易于追踪;
  • LiveData 膨胀: 复杂的页面需要定义多个 MutableLiveData,并且都需要暴露为不可变的 LiveData。

MVI(Model-View-Intent)

MVI 模式的改动在于将 View 和 ViewModel 之间的多数据流改为基于 ViewState 的单数据流。

MVI 将代码分为以下四个部分:

  • View:Activity、Fragment 和 XML 文件,与 MVVM 中 View 的概念相同;
  • Intent:定义数据操作,是将数据传到 Model 的唯一来源,相比 MVVM 是新的概念;
  • ViewModel:存储视图状态,负责处理表现逻辑,并将 ViewState 设置给可观察数据容器;
  • ViewState:一个数据类,包含页面状态和对应的数据。

总结

MVVM 和 MVP 的思想是相同的,最本质的概念就是 Activity 里做的事情太多了,所以要把 Activity 中与 UI 无关的部分抽离出来。在 MVP 里叫作 Presenter,在 MVVM 里叫作 ViewModel。而不论是 MVP 中的约定接口,还是 ViewModel 里的观察者模式,这些都是实现上的细节而已。

参考

[1] 正确认识 MVC/MVP/MVVM
[2] sockeqwe/mosby
[3] architecture-samples