前言
如何管理UI去采用不同的管理模式。耦合度高时现象,关注分离式手段,易于维护和易测试性式结果,模式可复用式经验。
MVC
Android默认的设计
- View:Layout XML文件
- Model:负责管理业务数据逻辑,如:网络请求、数据库处理
- Controller:Activity负责处理表现逻辑
MVC解决Activity代码太多问题。造成:Activity柔和了视图和业务代码,分离程度不够。
MVP
- View:Activity和Layout XML文件
- Model:负责管理业务数据逻辑,如:网络请求、数据库处理
- Presenter:负责处理表现逻辑
存在缺点:
- 双向依赖:View和Presenter双向依赖,View层改变,Present也要调整
- 内存泄漏风险:Presenter持有View层引用。
- 协议接口类膨胀:View层和Presenter交互复杂时,需要定义多个接口,不好维护。
MVP优化建议:
- 对P层造成的内存泄漏,使用Lifecycle组件结合线程池来解决,Lifecycle用来同步P层与Activity的生命周期,并在合适的时机取消线程池的的任务
- 为了避免P层过度臃肿,把不需要放到P层的代码挪到Activity中,保证P层代码纯正,保证功能单一原则。
MVVM
- View:Activity和Layout XML文件
- Model:负责管理业务数据逻辑,如:网络请求、数据库处理
- ViewModel:存储视图状态,负责处理表现逻辑,将数据设置给可观察数据容器
缺点:
- 多数据流:View和ViewModel交互分散,缺少唯一修改源,不易于追踪
- LiveData膨胀:负责的页面需要定义多个MutableLiveData并且需要暴露不可变的 LiveData。
DataBinding ViewModel LiveData 组件是Google帮助我们实现MVVM模式提供的框架结构并不是MVVM本质。
- Lifecycle:生命周期状态回调
- LiveData:可观察的数据存储类
- dataBingding:可自动同步UI和data不用再findViewById
- ViewModel:存储界面相关的数据,这些数据不会在手机旋转等配置改变时丢失
MVI
将View和ViewModel之间多数据流改为基于ViewState的单数据流。
- View:Activity和Layout XML文件,与MVVM中View的概念相同
- Intent:定义数据操作,将数据传到Model的唯一来源,相比MVVM时新的概念
- ViewModel:存储视图状态,负责处理表现逻辑,并将ViewState设置给可观察数据容器
- ViewState:一个数据类,包含也买你状态和对应的数据
View和ViewModel之间的多个交互(多LiveData数据流)变成了单数据流。无论View有多少个视图状态,只需要订阅一个ViewState便可以获取所有状态,再根据ViewState响应。
- 唯一可信源:数据只有一个源(ViewModel),与MVVM的思想相同。
- 单数据流:View和ViewModel之间只有一个数据流,只有一个地方可以修改数据,确保数据是安全稳定的。并且View只需要订阅一个ViewState就可以获取所有状态和数据,相比MVVM是最新特性。
- 响应式:ViewState包含页面当前状态和数据,View通过订阅ViewState就可以完成页面刷新,相对于MVVM是新的特性
MVI缺点:
- State膨胀:所有视图变化都转换为ViewState,需要管理不同状态对应数据。实践中根据状态之间的关联据欸的那个使用单数据流还是多数据流
- 内存开销:ViewState是不可变的,状态变更时需要创建新的对象,存在内存开销
- 局部刷新:View根据ViewState响应,不容易实现局部diff刷新,可以使用Flow.distinctUntilChanged()来刷新减少不必要的刷新。
MVI不是一个权限的实际模式,设计理念和Redux模式类似。
总结
MVVM和MVP思想相同,本质的概念是把Activity中与UI无关的部分抽离出来,交给其他类做。在MVP里叫Presenter(约定接口),在MVVM里叫ViewModel(观察者模式)。
MVI与前者区别在于强调严格的单数据流,命令式的开发模式转换为响应式开发模式。从React到Flutter,从MVI到Compose,响应式编程像是未来的趋势。