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 vs MVC
| 维度 | MVC | MVVM |
|---|---|---|
| View 更新 | Controller 手动更新 | 双向绑定自动同步 |
| 中间角色 | Controller(协调) | ViewModel(暴露可观察数据) |
| 耦合 | Controller 和 View 耦合 | View 和 ViewModel 松耦合 |
| 典型 | Spring MVC、早期 Web | Vue、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 的核心思想。
