一、MVI架构是什么
MVI
与 MVVM
很相似,其更加强调数据的单向流动和唯一数据源。
定义分为以下部分:
- Model:UI状态,例如页面加载状态、控件位置等都是一种状态。
- View:View,可能以Android View(Activity、Fragment)或者Compose形式呈现。View中所有变化,都通过观察Model的变化实现
- Intent:用户意图,用户通过点击、滑动等在View上动作产生的各种操作,被包装成意图,单向传递给Model。
MVI中的具体层级:
其中的ViewState就是与MVVM产生差别的部分。
MVVM中,UI与数据是进行了双向绑定的,而MVI中,所有用户操作被定义成了单向流。所有UI变化只有从ViewModel中订阅才可以感知。
二、MVI的作用
MVI架构是在前身MVVM基础上的优化升级版,其最大的变化就是单向数据流,所有的用户意图只由ViewModel接收并处理,所有的UI变化只由ViewModel传递的UiState决定。流向更纯粹,解耦更清晰。
同时MVI将MVVM使用的LiveData进行了优化,用StateFlow取代,将所有UI与数据变化集中在了Model层。
三、具体分层
MVI架构分为3层:界面层、网域层、数据层
具体层级:
UI Layer(界面层)
界面的作用是在屏幕上显示应用数据,并充当主要的用户互动点。每当数据发生变化时,无论是因为用户互动(例如按了某个按钮),还是因为外部输入(例如网络响应),界面都应随之更新,以反映这些变化。实际上,界面是从数据层获取的应用状态的直观呈现。
Domain Layer(网域层)
UseCase
作用
网域层负责封装复杂的业务逻辑,或者由多个 ViewModel 重复使用的简单业务逻辑。此层是可选的,因为并非所有应用都有这类需求。因此,您应仅在需要时使用该层,例如处理复杂逻辑或支持可重用性。
网域层具有以下优势:
- 避免代码重复。
- 改善使用网域层类的类的可读性。
- 改善应用的可测试性。
- 让您能够划分好职责,从而避免出现大型类。
Data Layer(数据层)
Repositories和Data Sources的层级
Repo中包含network与Database数据源
数据层由多个存储库组成,其中每个存储库都可以包含零到多个数据源。您应该为应用中处理的每种不同类型的数据分别创建一个存储库类。例如,您可以为与电影相关的数据创建一个 MoviesRepository
类,或者为与付款相关的数据创建一个 PaymentsRepository
类。
命名惯例
数据类型 + Repository。
例如:NewsRepository
、MoviesRepository
或 PaymentsRepository
。
Demo样例
Demo中的目录结构
demo项目在根目录下分了4个文件夹:data、domain、ui,以及用于将除界面意外所有内容注入APP的依赖注入框架koin(官方推荐使用Hilt,但个人觉得相比如全是注解的Hilt,Koin更简洁更优雅)
UI层
UI层分为4个文件夹:
- adapter。RecyclerView等的适配器
- ui。View或Compose的界面
- uistate。直接关联对应界面的界面状态
- viewmodel。处理界面与界面状态交互状态容器
Ui
展示Ui,传递用户意图。
UiState
Ui层与Model层沟通的模型。
ViewModel
其中是负责响应用户的操作,并与数据层或网域层沟通,得到结果后通过stateFlow将结果反馈给UI层。
网域层
网域层内只包含一层,内部都是封装着复杂业务逻辑的UseCase
UseCase中的内容
UseCase类的入参是Repository与其他UseCase。用于封装业务逻辑。
数据层
数据层分为repository和source两个文件夹:
-
repository。对外暴露的local与remote中最简化元操作。
-
source。所有数据来源,仅对Repository可见
-
local。本地数据,demo中使用的是Room
- bean。封装的业务模型
- dao。Room所需的Dao文件用于具体的CURD操作
- db。定义的DB接口及DB接口的实现,仅暴露repository中所需要的元操作
-
remote。远程数据,用于网络请求,demo未找到合适接口,暂不举例
-
Repository
对外暴露的local与remote中最简化元操作。
Source
bean。封装的业务模型
dao。Room所需的Dao文件用于具体的CURD操作
db。定义的DB接口及实现,仅暴露repository中所需要的元操作
四、注意
MVI也有很多缺点,例如每次更新UI都会新建UIState的新对象,这也是开销。
所有的架构都是为项目服务的,请根据自身项目情况选择最适合的架构。