其实最初的想法就是想应付面试的,我在想这么大的话题,怎么在面试中展开说,不想只是对名字做翻译,到底该怎么说才能在面试中拿个高分,带着这个初衷,就有了下面这些文字。
前言
这篇文章介绍顺序是 MVC-MVP-MVVM-MVI,介绍完毕后,最后再对比差异。
为了方便阅读,解释一下:A类持有B类引用,则A → B 。
另外整篇文章只涉及 android,因为比如 MVVM 在其他类型项目中可能也有使用,但是最终的表达形式可能略有差异,eg:android 有自己的 livedata/viewmodel,所以加一个针对 android 的前提条件。
android 官方推荐的应用架构指南链接先奉上,建议大家多读。
欢迎大家读完后点赞+收藏+指正~
MVC

- View:视图层,android 中的 xml文件/Activity/Fragment,
- Controller:控制层,但在开发过程中会把 Controller 层的任务也放到 Activity/Fragment 层,导致 View 层臃肿,耦合严重。
- Model:模型层,一般是网络请求、数据库相关的操作。
View 层传递用户的输入事件到 Controller,Controller 整合后向 Model 发起数据请求,请求结果回来后,更新UI。
MVP

Presenter:逻辑层,去更新UI时,调用的是View 层接口,而不再是具体的实现,这样逻辑层和视图层完全分离;
View: UI层,比 MVC 中的 UI层要更纯粹,可以不含任何逻辑代码,只负责UI展示;
Model:模型层和 MVC 一样,没变化;
实在懒得写demo,具体可以看看这个项目github-mvp-demo ,另外 mvp 有很多种变体,上述demo 只是mvp 其中一种。
优点:
- 利用 Presenter 简化了 MVC 中 Controller 部分的代码;
- View 层只需要关注自身的UI更新;
面向接口通信
缺点:
- 单 Activity + 多 Fragment 场景下,无法便捷合理的实现数据共享;
- Presener 持有了 View 层的引用,未完全解偶;
MVVM

MVVM 中的 VM 即ViewModel,是一种业务逻辑或屏幕级状态容器。它的主要优点是,它可以缓存状态,并可在配置更改后持久保留相应状态
。这意味着在 activity 之间导航时或进行配置更改后(例如旋转屏幕时),界面将无需重新提取数据。
老规矩,懒得写demo,移步这里看 github-mvvm-demo。
数据驱动
是 MVVM 的关键词,ViewModel 不再主动调用方法去更新界面,而是主动更新数据,同时界面采用观察数据的方式,等待被更新,这里也是响应式编程思想
的体现。另外这一次真正实现单向箭头,即 View 层持有 ViewModel 层引用,ViewModel 层持有 Model 层引用。实现这种方式其实借助了特别重要的类 LiveData。
优点:
- 数据驱动,响应式编程思想
- 业务逻辑和界面展示分离
- 借助于 LiveData ,跨界面之间的业务逻辑共享以及通信变得轻松,eg:单Activity+多Fragment 之间的数据共享和传递
- LiveData 不仅使得业务层成为数据持有者以数据驱动刷新界面,还避免了生命周期问题以及内存泄漏风险。
缺点:
- 界面需要观察多个 ViewModel 提供的数据,这导致界面状态的一致性难以维护。
- 成员变量是增加复杂度的利器,因为它可以被任何成员方法访问。也就是说,新增业务对成员变量的修改可能影响老业务的界面展示。同理,当界面展示出错时,也很难一下子定位到是哪个请求造成的。「这也是我司项目的问题,一个 View 的更新 需要关注 4-5 个 LiveData 的变化,导致需求修改时特别容易出错,挺痛苦的...」
MVI
下面看本系列第2篇文章:「架构篇 2」认识 MVC / MVP / MVVM / MVI