Skip to content

MVVM 是 Vue、React、Android DataBinding 的核心,是《MVC 模式》→《MVP 模式》之后演化的下一步。这篇讲清它解决了前面模式的什么问题、"双向绑定"到底怎么工作、以及 ViewModel 和 Model 的区别。

一、解决什么问题:View 要手动更新(MVC 和 MVP 共同的痛点)

"手动更新 View"这个痛点,MVC 和 MVP 都有,只是"谁在手动更新"不同:

java
// MVC:Controller 手动更新 View
model.addAttribute("order", order);   // 手动塞数据
return "order/detail";                 // 手动指定视图

// MVP:Presenter 手动更新 View(换汤不换药)
view.showSuccess();                    // Presenter 手动调 View 接口更新

MVC 是 Controller 手动更新,MVP 是 Presenter 手动更新——只要数据一变,总得有个人去手动刷新 View。视图越复杂,这种"手动同步"越容易漏、越容易乱。

MVVM 的思路是:View 只声明"我绑定谁",数据一变 View 自动跟着变,谁都不用手动更新。这就是"双向绑定"。

二、MVVM 三部分 + 双向绑定

部分职责变化
Model数据 + 业务逻辑和 MVC 一样
View展示 + 交互只声明绑定,不写更新逻辑
ViewModel暴露可观察数据 + 命令新增:View 的"模型"

核心是 ViewModel + 双向绑定

  • ViewModel 把数据包装成"可观察的"(observable)
  • View 绑定这些数据——数据一变,View 自动刷新
  • View 的输入自动写回 ViewModel 的数据(双向)

用 Vue 看最直观:

html
<!-- View:模板,只声明绑定,不写更新代码 -->
<div>{{ message }}</div>
<input v-model="message">   <!-- 双向绑定:输入自动写回 message -->
js
// ViewModel:数据 + 逻辑
new Vue({
    data: { message: 'hello' },   // 数据变了,{{ message }} 自动刷新
});

双向绑定是两个方向都自动:

  • 数据 → 视图message 数据一变(代码里改), 和输入框的显示自动刷新
  • 视图 → 数据:用户在输入框里敲字,message 数据自动更新

中间没有任何手动更新的代码。

三、Android DataBinding 落地

Android 里 MVVM 的标配是 DataBinding + ViewModel:

kotlin
// ViewModel:暴露可观察数据
class UserViewModel : ViewModel() {
    val name = MutableLiveData("BinMaker")   // 可观察数据
    fun updateName(n: String) { name.value = n }
}

// View(layout XML):声明绑定,不写更新逻辑
// <TextView android:text="@{viewModel.name}" />
// <Button android:onClick="@{() -> viewModel.updateName(...)}" />

name.value 一变,绑定了 @{} 的 TextView 自动刷新——View 里没有一行手动更新代码

MVVM:View 声明绑定,ViewModel 数据一变 View 自动刷新

四、MVVM vs MVC

维度MVCMVVM
View 更新Controller 手动更新双向绑定自动同步
中间角色Controller(协调)ViewModel(暴露可观察数据)
耦合Controller 和 View 耦合View 和 ViewModel 松耦合
典型Spring MVC、早期 WebVue、React、DataBinding

一句话:MVVM 用"双向绑定"干掉了 MVC 里"手动更新 View"这个体力活

五、MVVM 的问题(引出 MVI)

MVVM 用久了也有痛点,主要是状态分散

  • 一个界面可能有多个 LiveData/多个双向绑定,状态散落在各处
  • 状态怎么变的、什么时候变的,追踪困难(双向绑定让数据流不透明)
  • 复杂界面下,多个状态互相影响,bug 难排查

这正是《MVI 模式》要解决的——用"单向数据流 + 不可变状态",让状态变化有迹可循。

小结

  • MVVM 用"双向绑定"解决 MVC 手动更新 View 的痛点
  • 三部分:Model(数据)+ View(声明绑定)+ ViewModel(可观察数据 + 命令)
  • View 不写更新逻辑,数据一变自动刷新
  • 落地:Vue v-model、Android DataBinding + LiveData
  • 遗留问题:状态分散、数据流难追踪 → 引出 MVI

下一步看《MVI 模式》——它用"单向数据流"解决 MVVM 状态分散的问题,是 Compose、Redux 的核心思想。