MVC、MVP、MVVM
1、MVC(Model.View.Controller)
- 模型层(Model):业务逻辑对应的数据模型,与View无关,与业务有关
- 视图层(View):使用XML或者Java代码界面进行描述
- 控制层(Controllor):通常指Activity/Fragment。或者由其控制的业务类
主要处理逻辑:View触发事件,controller响应并处理逻辑,调用Model,Model处理完成后将数据发送给View。View更新
存在的问题:Activity责任不明,十分臃肿
Activity由于其生命周期的功能,除了担任View层的部分职责。还要承担Controller层的职责(业务逻辑的处理)
随着界面增多&逻辑复杂度提高,Activity类的代码量不断增加。越来越臃肿
2、MVP(Model、View、Presenter)
- 模型层(Model):数据模型,用于获取和存储数据。负责管理业务数据逻辑,如网络请求,数据库处理
- 视图层(View):Activity/Fragment
- 控制层(Presenter):负责业务逻辑
主要处理逻辑:以Presenter为核心。负责从model获取数据,并填充到View中。MVP使Model和View不再联系,完全解耦
在使用MVP框架时,View层与Model层不通信,都是通过Presenter层传递,并且Presenter层与具体的View是没有直接关联的。而是通过定义好的接口进行交互,这就可能导致有大量的接口生成。代码复杂繁琐,不好维护。
规范:
1、接口规范化(封装父类接口以减少接口的使用量)
2、使用第三方插件自动生成MVP代码
3、对于一些简单的界面。可以选择不使用框架
4、根据项目复杂程度,部分模块可以选择不使用接口。
优点:
1、耦合度更低:通过Presenter实现数据和视图之间的交互,完全隔离了View层和Model层。二者互不干扰
2、Activity代码变得简洁:简化了Activity职责,仅负责UI相关操作。其余复杂的逻辑代码提取到了Presenter层中进行处理
缺点:
1、双向依赖。View和Presenter是双向依赖的。一旦View做出改变时,Presenter也需要做出调整。
2、内存泄漏风险:Presenter持有View的引用。当用户关闭了View层,但Model层仍然在进行耗时操作。(解决办法:弱引用/onDestroy回收Presenter)
3、协议接口膨胀:View层和Presenter层的交互需要接口方法。当交互非常复杂时,需要定义很多接口和回调方法。不好维护
3、MVVM(Model、View、ViewModel)
- Model(数据层) : 负责管理业务数据逻辑,如网络请求,数据库处理。
- View层 : Activity/Fragment.继承LifecycleActivity/LifecycleFragment
更新UI控件显示,包括状态以及数据,由ViewModel驱动
监听UI事件及其生命周期,驱动ViewModel
-
ViewModel: 存储视图状态,负责处理表现逻辑,并将数据设置给可观察数据容器。
缺点:
1、多数据流:View与ViewModel的交互分散。缺少唯一修改源,不易追踪
2、LiveData膨胀:复杂的页面需要定义多个MutableLiveData,并且都需要暴露为不可变的LiveData
实现细节:View和Presenter从双向依赖变成View可以向ViewModel发指令,但ViewModel不会直接向View回调。而是让View通过观察者模式去监听数据的变化。有效规避了MVP双向依赖的缺点。
使用MVVM框架步骤:
-
提供View、ViewModel以及Model三层
-
将布局修改为DataBingding布局
-
View与ViewModel之间通过DataBinding进行通信。
-
获取数据并展示在界面上。
4、MVI
MVI模式的改动在于将View和ViewModel之间的多数据流改为基于ViewState的单数据流
MVI将代码分为以下4个部分:
- View:Activity/Fragment的XML文件。
- Intent:定义数据操作。是将数据传到Model的唯一来源。相比MVVM是新的概念
- ViewModel:存储视图状态,负责处理表现逻辑,并将ViewState设置给可观察数据容器
- ViewState:一个数据类。包含页面状态和对应的数据