MVC、MVP、MVVM、MVI 应用架构知识盘点

211 阅读3分钟

什么是架构,以及为什么需要架构设计

  • 现象:耦合度高
  • 问题:类文件冗长,维护不易,扩展困难,复用程度低,难测试
  • 目标:易维护,易测试
  • 手段:解耦合,关注点分离
  • 模式:总结出来的几种通用方法(MVC,MVP,MVVM,MVI)

MVC

Controller与View互相引用, Controller与Model互相引用

image.png

  • View:xml布局文件
  • Model:管理业务数据,如网络请求、数据库
  • Controller:即Activity,处理表现层逻辑

优点

  • 初步解决Activity代码冗长的问题,将数据从Activity中分离出去

缺点

  • Activity里既要处理View、也要处理业务逻辑,职责不清晰

MVP

Presenter与View通过接口间接引用,Presenter与Model互相直接引用

image.png

  • View: xml布局文件,Activity,Fragment
  • Model:管理业务数据,如网络请求、数据库(同MVC)
  • Presenter:处理表现逻辑

优点

  • 将Activity中分离出业务逻辑代码,使Activity只处理显示层的事务,它的职责更加清晰

缺点

  • 双向依赖:View、Presenter两层互相依赖,其中一方如果变动,另一方也必须跟着变
  • 内存泄漏:Model、Presenter、View存在链式的引用,如果Model存在耗时操作,处理不当的话会使View层的Activity泄漏。通过弱引用、手动回收可以避免,但增加了工作量和风险点
  • 协议接口膨胀:View、Presenter两层通过接口实现互相调用,逻辑复杂会导致接口类迅速增多

MVVM

View观察ViewModel,后者不引用前者,只是作为数据的发送源。ViewModel和Model互相引用

image.png

  • View:Activity 和 Layout XML 文件,与 MVP 中 View 的概念相同;
  • Model:负责管理业务数据逻辑,如网络请求、数据库处理,与 MVP 中 Model 的概念相同;
  • ViewModel:存储视图状态,负责处理表现逻辑,并将数据设置给可观察数据容器。

Lifecycle, LiveData, Databinding, ViewModel组件是 Google 为了帮助我们实现 MVVM 模式提供的架构组件,它们并不是 MVVM 的本质,只是实现上的工具。

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

优点

  • 解除ViewModel对View的依赖,降低耦合度
  • 防止内存泄漏

缺点

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

MVI

在View与ViewModel之间,抽象出ViewState的概念,含义是“View当前的显示状态”。一个View只需要关注一个ViewState

image.png

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

优点

  • 唯一可信来源:ViewModel
  • 单一数据流:View只需要订阅ViewState
  • 响应式:通过订阅完成自动刷新View

缺点

  • State膨胀:实践中根据需求选择单/多数据流,不必拘泥于单数据流
  • 内存开销:ViewState是不可变类,意味着无法通过对象池实现复用
  • 局部刷新:整个View由一个ViewState决定,实践中由Flow#distinctUntilChanged()等技术帮助刷新

参考资料