Skip to content

参考

基于 Martin Fowler「GUI Architectures / Passive View / Presentation Model」+ MDN MVC 词条 + React/Vue/Angular 官方文档编写,对照 2026-07 框架现状

速查

  • 三模式共同根:Separated Presentation(分离表现层)——Model 不依赖 UI 框架
  • MVC:Model(数据 + 业务)/ View(展示 + 观察 Model)/ Controller(输入分发),Observer Synchronization
  • MVP:Presenter 完全中介,View 对 Model 零可见;Passive View / Supervising Controller 两变体
  • MVVM:ViewModel 不持 View 引用,Data Binding + Change Notification 同步
  • React:单向数据流(data down / events up),Lifting State Up,无双向绑定
  • Vue:one-way-down;v-model = :modelValue + @update:modelValue
  • Angular:组件类 = ViewModel,模板 = View;[(ngModel)] banana in a box
  • 可测试性:Passive View > MVVM/PM > Supervising Controller > 经典 MVC
  • Humble Object:把逻辑从难测的 View 推到可测的 Presenter/ViewModel
  • 完整说明见 入门 / 深度指南

三模式对比表

维度MVCMVPMVVM
起源1970s Smalltalk-80Mike Potel 1996;Fowler 2004 系统化John Gossman 2005(WPF);源头 Fowler PM 2004
中间层ControllerPresenterViewModel
中间层持 View 引用短期(处理手势时)长期持不持
View 对 Model 可见性有(观察 Model)(彻底解耦)仅通过 VM 间接
同步机制Observer SynchronizationPresenter 显式命令Data Binding + Change Notification
可测试性最低高(Passive View 最高)
典型框架Smalltalk / 早期 SwingWindows Forms / 部分企业应用Angular / Vue / WPF
适用场景多屏自动同步需要严格单测声明式框架的表单 / 复杂 UI

MVP 两变体对比

维度Passive ViewSupervising Controller
Presenter 操纵范围全部 widget(含数据填充)仅复杂逻辑
View 对 Model 可见性有(仅简单同步用绑定)
样板代码
可测试性最高
适用场景严格单测 / UI 框架替换可能大多数场景,平衡可测与样板

现代框架映射表

框架模式归属关键证据反模式警示
React 19单向数据流(非 MVVM)无双向绑定;data down / events up;Lifting State Up受控/非受控混用、子组件 mutate prop
Vue 3.5类 MVVM(声明式 + 响应式)v-model 是 props + emit 语法糖,本质单向子组件 mutate prop、深层 v-model 串联
Angular 17-20MVVM 直接实现组件类 = VM;[( )] 两路绑定由 signal 驱动深层 [(ngModel)] 串联

React 单向数据流三原则

text
1. data flows down     父 → 子 通过 props
2. events flow up      子 → 父 通过 callback
3. Lifting State Up    多子组件共享状态 → 提升到共同父

Vue v-model 脱糖

vue
<Child v-model="text" />
<!-- 等价于 -->
<Child :modelValue="text" @update:modelValue="text = $event" />

Angular [(ngModel)] 脱糖

ts
<input [(ngModel)]="name" />
// 等价于
<input [ngModel]="name" (ngModelChange)="name = $event" />

可测试性排序(完整)

排名模式原因
1Passive ViewPresenter 纯逻辑,Test Double 替身 View 即可测
2Presentation Model / MVVMViewModel 不持 View 引用,纯逻辑测试
3Supervising Controller简单同步散落在 View,部分逻辑无法纯测
4经典 MVCView 与 Model 双向耦合,View 难脱离框架单测

反模式清单(避坑速查)

反模式修正
Fat Controller(业务 + 视图 + 数据全塞 Controller)拆 Service / Repository,Controller 只做分发
View 直接访问 / 观察 Model(违反 MVP)View 只通过 Presenter/VM 中介
子组件直接 mutate prop(Vue)emit 事件或用 defineModel / computed 代理
深层嵌套滥用 v-model / [(ngModel)]大状态用 store,跨层 provide/inject 单向传递
Controller 直接操纵 View(MVC 退化)View 由 Model 通知触发刷新
ViewModel 持有 View 引用(MVVM 退化)纯 Data Binding 解耦
受控/非受控混用且数据源不唯一(React)明确「谁拥有这块状态」,保持 SSOT
领域业务规则写进 ViewModel/Presenter业务下沉到 Model/Service 层

历史脉络

年份事件
1970sTrygve Reenskaug 在 Smalltalk-80 提出 MVC
1996Mike Potel 提出 MVP
2004Martin Fowler 在 eaaDev 系统化 MVP,拆分为 Passive View / Supervising Controller;同年提出 Presentation Model
2005John Gossman 在 Microsoft WPF 团队提出 MVVM(PM 的特化)
2010s单页应用兴起:Knockout / Ember / AngularJS 把 MVVM 引入前端
2014+React 出现,主打单向数据流 + Flux/Redux,与 MVVM 形成两条路线
2024+Angular 17+ 全面转向 Signals;Vue 3.5 保持响应式;React 19 仍无双向绑定

版本现状(2026-07)

三大模式理论无版本漂移——都是 30+ 年稳定的设计模式。框架实现持续演进:

框架版本数据流模型
React19(2024-12 GA)单向 + Actions/use 钩子 + Server Components,仍无框架级双向绑定
Vue3.5(2024-09)one-way-down + v-model 语法糖 + Composition API
Angular17-20(2024-2025)Signals(signal() / computed() / model()),zone.js 逐步可选化,变更检测更细粒度

三模式理论侧稳定,框架侧持续向 signal / 细粒度响应式演进。

官方资源