「架构篇 2」认识 MVC / MVP / MVVM / MVI

前言

接本系列第一篇文章 「架构篇 1」认识 MVC / MVP / MVVM / MVI,建议大家读完再看这里。

学习 MVI 的话,强调意图,强调流。有一种将流用到极致的感觉,所以如果不能灵活运用 Flow 相关 API 的话,会较吃力,建议先学习 Flow,可以用下面 2 篇文章扫盲:

MVI

先说一点,Google 目前从未在 Android Developers 中提及 MVI,但是 MVI(Model-View-Intent )这一架构模式在 Android 开发中很流行,主要是因为 MVI 的理念(单向数据流、不可变状态)和 Google 推出的现代应用架构一致。 MVI 与 MVP/MVVM 不是非此即彼的关系,它们是不同维度的。

从界面发出的数据叫Intent,而界面接收的数据叫State,这样整个界面的刷新流程就形成一条Unidirectional Data Flow(UDF),即单向数据流。

MVI 关心的不是具体的界面状态持有者,而是整个更新界面数据链路的流动方式和方向。

在 MVI 中,把界面的一次展示理解为单个 State 的一次渲染。相较于 MVVM 中一个界面可能被分拆为多个 LiveData,State 这种唯一数据源降低了复杂度,使得代码容易维护。

界面层

使用名为 XUiState 的data class,来定义界面状态,且类中的属性皆是 val 的,以此来保证单一数据源,

kotlin 复制代码
//在viewmodel 定义如下 uiState
private val _bgmEntranceUiState = MutableStateFlow<BgmEntranceUiState?>(null)  
val bgmEntranceUiState: StateFlow<BgmEntranceUiState?> = _bgmEntranceUiState

//在fragment接收此flow
fun initObser(){
    launchCoroutine {  
        bgmEntranceUiState.collect {
        //处理页面中某一个部分的 1组view,在这个模式之前使用MVVM,
        //这1组view 需要接受多个 livedata的 observer,当发现问题时,
        //无法快速确定哪个数据源导致的变化
        }  
    }
}

这个图中可以观察一下,状态向下流动、事件向上流动的这种模式称为单向数据流 (UDF)

界面层包含与界面相关的状态和界面逻辑,相应的数据和业务逻辑是放到数据层。

数据层

这里 ViewModel 持有 Repository 引用,推荐使用 依赖项注入模式并使用 Hilt 库

网域层

最终架构模型

我负责的歌房/直播业务,目前没有网域层,其余按照官方推荐架构已经重构过,其实推荐大家按照上面的官方文档链接读完,再看看 nowinandroid 项目,结构清晰易阅读,也更容易理解了。

写完感触

其实上班这么长时间来,回头一看:

第一家公司没有架构可言,主打就是完成功能;

第二家公司MVC,后期就是 Activity 超级大;

第三家公司就是 MVP,那时候感觉最深的就是每次新起一个模块一堆模版代码;

目前这家公司,我负责歌房/直播业务,除 C++ 层接触不多,其余 TRTC 模块,美颜模块,性能优化模块都有所触及,随着业务越来越复杂「公认复杂」,最初 MVVM 明显感觉到修改业务的复杂度变得很高,然后重构到现在的 MVI,歌房/直播里有新增业务模块,基本很少改动到原有的业务代码,各个业务解偶,目前比较满意「但还有很多老业务冗余在 Activity/Fragment/ViewModel 中,哈哈哈... 目前原则就是 不动就不会有大bug」有心情的话,接下来会把歌房的架构画一画,拿出去面试也能够清晰了然。

接下来的计划就是重点看 C 这块,把演唱底层 系统学完。

参考链接

ViewModel

相关推荐
塔望品牌咨询41 分钟前
品牌战略的“系统工程”:从“一句口号”到“五维系统”的架构方法
架构·消费品·消费战略·塔望消费战略·食品·快消品
Ulyanov1 小时前
构建企业级雷达电子战仿真引擎的工程化基础 第一篇:CI/CD流水线与自动化测试体系
python·ci/cd·架构·系统仿真·雷达电子战仿真
华科易迅8 小时前
MybatisPlus增删改查操作
android·java·数据库
黄林晴8 小时前
Android17引入DeliQueue新架构: 为什么要重写MessageQueue?
架构
SHoM SSER9 小时前
MySQL 数据库连接池爆满问题排查与解决
android·数据库·mysql
黄林晴9 小时前
Android 17 取色器 API:无需权限,一行 Intent 跨应用取色
android
学嵌入式的小杨同学9 小时前
STM32 进阶封神之路(三十二):SPI 通信深度实战 —— 硬件 SPI 驱动 W25Q64 闪存(底层时序 + 寄存器配置 + 读写封装)
c++·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
RestCloud9 小时前
API网关 vs iPaaS:企业集成架构选型的本质差异与2026年选型指南
架构·数据处理·数据传输·ipaas·ai网关·集成平台
ShineWinsu10 小时前
对于Linux:进程优先级、进程切换以及进程调度的解析
linux·面试·笔试·进程·进程切换·进程调度·进程优先级
程序员陆业聪10 小时前
别再说 Flutter 是唯一选择了——KMP 正在悄悄抢走它的地盘
android