承接上一篇《MVVM 与 DataBinding:数据驱动的开端》,那一篇确立了「状态是数据」这个内核。这一篇继续推进:既然状态是中心,那么谁有资格修改它、能改几次、从哪改,就成了下一个要解决的问题。MVVM 留下了三个口子,MVI 用「单一入口 + 不可变状态 + 显式事件」把它们收口。
结论先行:MVI 的价值不在于多了 Intent 和 Effect 两个类,而在于建立了一条可验证的不变式——状态只能通过处理 Intent 产生,且每次处理产生一个新状态。这条不变式带来两个直接好处:状态可被完整回放,逻辑可被完整测试。
一、MVVM 留下的三个口子
先说清 MVI 要解决什么,否则「单向数据流」只是口号。
口子一:状态修改点分散。MVVM 里状态可以在任意私有方法里改:
class CartViewModel : ViewModel() { private val _state = MutableStateFlow(CartState()) // 修改点 1:初始化 init { _state.value = CartState(isLoading = true) } // 修改点 2:加载成功 fun load() { viewModelScope.launch { _state.value = CartState(items = repo.load()) } } // 修改点 3:加购 fun add(item: Item