背景
本文梳理记录MVC、MVP、MVVM、MVI概念和演进,以及自己的理解。
面试时经常被问到,MVC MVP MVVM他们到底是什么?如何搭建一个页面?需要具体问题具体分析,思辨的能力。
因为核心算法 -> 操作系统/app 很少变化,页面给用户看的->新需求不断的被改变,如果页面很复杂可以拆为多个Vew
。
一、几种模式
以下对几种已有MVC、MVP、MVVM模式介绍和对比。
1.MVC
数据(Model) : 数据+对数据进行的操作(不依赖视图的操作)=》Rxjava 变换
视图(View) : 不同的模式有不同的定义;xml+activity+fragment = view合集
逻辑(Controller): view和model的通信和交互
特点
- 进步:mvc相对一个文件打天下,分离了Model和Controller。
- 缺陷:
1、Controller和View难以完全解耦(Activity即是控制器,又承担了视图层的工作)
2、Activity太过臃肿,还承担了部分业务逻辑
3、controller的权利太大(activity)=》什么事情都能做=》需求多变,activity越改会变得越来越大,越来越臃肿,来龙去脉。
2.MVP
和MVC区别:
1、Model和View不再进行直接通信,而是通过中间层Presenter来实现。
2、Acitivity功能被简化,不用再充当控制器,主要负责View层工作
特点(相对于MVC)
- 优点:
1、解决了MVC中Controller和View过度耦合的缺点,职责划分明确,更利于维护。
2、activity只剩下了view,presenter承担了view和model之间的交互,满足了单一职责原则,视图数据逻辑是清晰的 - 缺点:
1、当项目越来越复杂时,接口数量变多,Presenter层也将变得越来越臃肿。
2、引入了interface,方法增多,增加一个方法要改几个地方;哪里有压迫哪里就有反抗
MVP相对mvc: - 使用建议:
1、接口规范(封装父类接口减少接口使用数量)
2、使用第三方插件自动生成MVP代码
3、对于一些简单的界面,推荐不使用框架。
3.MVVM
MVVM是Model、View、ViewModel的简写,在MVP基础上实现了数据视图的绑定(DataBinding),当数据发生变化时,视图会自动更新;反之,视图被改变时,数据也自动更新。
mvvm:在使用的module和app的module都加入dataBinding{ enabled true}
viewBinding:只能省略findViewById viewBinding{ enabled true},不需要修改xml
dataBinding:除了viewBinding的功能还能绑定data,需要修改xml
特点
- 优点:
1、减少了接口数量
2、告别了繁琐的findbyid操作。 - 缺点,这里泼点冷水,MVVM也不完美。在大型工程中,总结会遇到如下问题:
1、滥用LiveData造成系统内存管理负担,我们都知道LiveData是谷歌官网提供的,在没有LiveData之前MVP强调对象用完及时释放,LiveData生命期很长;
2、业务复杂时LiveData和View相互依赖,导致View和ViewModel职责不清晰,这就要求开发人员遵循规范编写业务逻辑清晰,否则别人接手难度大;
3、Xml和代码耦合,不方便业务迁移;
4、DataBinding的使用增加了编译一定耗时,它在使用过程中中还是不是会出问题。
二、辩证的看
应用开发的原则
推荐:
- 遵循面向对象的SOLID原则,知乎图解
单一、开闭、里氏、接口隔离、依赖倒置、迪米特原则
- 视图、数据、逻辑分离
静态的角度,动态的角度:生命周期,什么情况下销毁
避免:
- 认为网络总是流程的
- 仅考虑能在自己手机上面运行
MVI
上图是已存在架构的对象持有关系。
Model:和其他模式不同,Model表示UI的状态。UI可能有不同的状态如数据加载、加载失败、用户操作等,每个状态都存储在模型的对象中。
View:MVI中的视图拥有一个可以接受不同模型状态并将它显示的容器。
Intent:非安卓中提供的意图对象,这里是指用户操作意图,通过Intent包装后发送给Model层进行数据请求。
优点
- 数据单向流动,容易对状态变化进行跟踪和回溯,可以把UI一次展示理解为单个State一次渲染
- 使用ViewState对State集中管理,只需订阅一个ViewState就可以获得页面所有状态。迫使程序员更全面的思考,将复用数据利用到最大。
- 更高效的性能,采用单向通信,可以获得更清晰严谨的代码,降低维护成本和测试难度。
总结
类型 | 创建过程 | A/F | 特点 | 缺点 | 建议 |
---|---|---|---|---|---|
MVC | C->M+V | C | 分离了Model和Controller | Controllder变复杂 | 适用简单、修改少的页面 |
MVP | V->P->M | V | 在MVC基础通过接口分离View和Model | P和V的交互变得琐碎复杂 | 核心、复杂、需求变更快的页面 |
MVVM | V->VM ->M | V | 在MVP基础上增加DataBinding,代码量更小 | XML和代码耦合 | 核心、复杂、需求变更快的页面 |
MVI | V->VM ->M | V | 解决MVVM存在问题,将用户意图和UIstate分离 | 有一定学习成本 | 核心、复杂、需求变更快的页面 |
MVI应该配合声明式UI框架或响应式Bloc模式,才配套,这里再简单介绍几种编程概念:
- 命令式编程,定义处理事情的逻辑+实现处理事情的方法;
- 响应式编程,异步编程范式,对观察者模式的拓展,专注于数据流和变化传递;
- 声明式编程,定义处理事情的逻辑框架;
- 函数式编程,定义处理事情的逻辑+通过函数实现基本功能。
参考