动机
作为一个 C# 程序员,早在 WPF 刚问世的时候就接触了 MVVM 这个概念,但由于当时(包括现在)主要做 WinForms 开发,所以只扫了一眼基本概念。后来借 Node.js 的东风,前端框架如雨后春笋,MVVM 被彻底炒热,作为彼时从未做过 OPA 的我,也顺势再次扫了一眼基本概念。一直以来,如同 MVC 一样,在没有实践之前,只有自以为是的肤浅理解。有些技术毕竟是绕不过去的,所以这次想真正意义上认识一下 MVVM。
目标
- MVVM 是为了解决什么问题而诞生的?
- 各组成部分的职责是什么?
TL ;DR
MVVM(Model-View-ViewModel)是一种软件架构模式,主要用于分离用户界面(UI)与业务逻辑。MVVM 的核心思想是通过数据绑定和命令机制,将 UI 与业务逻辑解耦,提升代码的可维护性和可测试性。M 负责业务逻辑,V 负责用户界面,VM 是 M 和 V 之间的桥梁,负责提供 V 所需的数据与命令。
MVVM 的诞生
其实种种前端架构的诞生,几乎都是为了解决同一个问题——用户界面与数据逻辑分离。事实上一直以来大家对此问题早有共识,用户界面与数据逻辑一定要尽可能分离开。这样做的好处是显而易见的,业务逻辑侧只需考虑如何反映核心业务以及数据流转,UI 侧则只需专心关注界面美化与操作体验。于是出现了各种耳熟能详的前端架构,比如 MVC、MVP 以及 MVVM 等。 发现了吗?他们都以 MV 开头。确实,M 与 V 都是很容易理解与实现的概念,M 只需关注业务,V 只需关注展示,但是难就难在他们之间如何交互!在实际项目中,M 与 V 是很难形成对应关系的,业务模型往往包含了丰富的信息,而特定的 V 只关注其中一部分信息或者需要的信息来自多个 M,这时就会纠结,如果把 M 直接给 V,里面很多信息其实是冗余的;为了 V 提供一个专用的 M,它在业务模型中又该以什么身份存在?事实上,缺少的并不是一个负责行为的 C 或者 P,而是一个作为 M 与 V 之间桥梁的“中间概念”。 MVVM 的诞生完美解决了这个问题,VM(ViewModel) 就是我们期待的那个“胶水”。
MVVM 的组成部分
-
Model:
- 职责: 负责管理应用程序的核心数据和业务逻辑。
- 特点: 独立于 UI,不直接与 View 或 ViewModel 交互,通常通过事件或数据绑定与 ViewModel 通信。
-
View:
- 职责: 负责定义用户界面的结构和外观。
- 特点: 通常由 XAML 或 HTML 等标记语言编写,通过数据绑定与 ViewModel 交互,尽量减少代码隐藏文件中的逻辑。
-
ViewModel:
- 职责: 作为 View 和 Model 之间的桥梁,提供 View 所需的数据和命令。
- 特点: 包含属性和命令,属性通过数据绑定与 View 同步,命令处理用户交互并更新 Model。
MVVM 的工作流程
-
数据绑定:
- View 通过数据绑定与 ViewModel 的属性连接,ViewModel 的属性变化会自动反映到 View 上。
- 例如,ViewModel 中的 UserName 属性变化时,View 中的文本框会自动更新。
-
命令绑定:
- View 中的用户操作(如按钮点击)通过命令绑定与 ViewModel 中的命令关联。
- 例如,按钮点击触发 ViewModel 中的 SaveCommand,执行保存操作。
-
通知机制:
- ViewModel 通过 INotifyPropertyChanged 接口通知 View 属性变化,确保 UI 同步更新。
MVVM 的优点
- 分离关注点: 将 UI 逻辑与业务逻辑分离,提升代码的可维护性和可测试性。
- 可测试性: ViewModel 不依赖 UI,便于单元测试。
- 可重用性: ViewModel 可在不同 View 中复用,减少代码重复。
- 数据绑定: 自动同步 UI 与数据,几乎无需编写更新UI的代码。