Android 架构模式
Android 开发常用的架构模式有 MVC、MVP 和 MVVM,目的都是为了将业务和视图的实现代码分离,从而使同一个程序可以使用不同的表现形式。
MVC
- Model:实体模型;
- View:对应于 Activity、Fragment 和 xml,负责用户交互和数据展示;
- Controllor:对应于 Activity 业务逻辑,数据处理;
数据流为:
- View 传送指令到 Controller;
- Controller 完成业务逻辑后,要求 Model 改变状态;
- Model 将新的数据发送到 View,反馈给用户;
_缺陷_:View 层和 Model 层是相互可知,耦合性大,像 Activity 或 Fragment 既在 Controller 层又在 View 层,造成工程的可扩展性可维护性非常差,承担的功能过多,自然代码量会增大。
MVP
- Model:负责管理业务数据逻辑,如网络请求、数据库处理;
- View:对应于 Activity、Fragment 和 xml,负责用户交互和数据展示;
- Presenter:负责业务逻辑处理,完成 View 和 Model 间的交互;
MVP 模式将 MVC 模式中的 Controller 修改为了 Presenter,同时改变了通信方向,Model 层和 View 层不直接通信,由 Presenter 层中转,使得 View 和 Model 解耦。
- Presenter 和 View、Model 的通信是双向的;
- View 与 Model 不直接通信,通过 Presenter 传递;
- 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
- Model: 负责管理业务数据逻辑。不仅包括实体类的定义,还需要对数据进行处理和读写。例如:使用 Retrofit 或 okHttp 进行网络请求,或数据库操作等;
- View: 对应于 Activity、Fragment 和 xml,只负责 UI 相关的工作;
- ViewModel: 负责业务逻辑处理,完成 View 与 Model 间的交互;
MVVM 的目标和思想 MVP 类似,利用数据绑定(Data Binding)、依赖属性(Dependency Property)、命令(Command)、路由事件(Routed Event) 等新特性,打造了一个更加灵活高效的架构。
与 MVP 相比,View 和 Presenter 从双向依赖变成 View 可以向 ViewModel 发指令,但 ViewModel 不会直接向 View 回调,而是让 View 通过观察者模式去监听数据的变化,有效规避了 MVP 双向依赖的缺点。
数据流如下:
- View 中使用 DataBinding 的 Command 来绑定事件和响应事件,触发网络请求;
- ViewModel 进行分析处理,调用 Model 的数据请求方法;
- Model 将收到的请求参数等信息封装,调用网络请求库(Retrofit 等)与服务器进行交互;
- 服务器将 json 数据返回到 Model 层中,ViewModel 在回调中收到返回的实体类对象;
- 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