模型-视图-视图模型(MVVM)是一种用于分离 UI 与非 UI 代码的架构设计模式。 使用 MVVM,可以在 XAML 中以声明方式定义 UI,并使用数据绑定标记将其链接到包含数据和命令的其他层。 数据绑定基础结构提供松散耦合,使 UI 和链接的数据保持同步,并将用户输入路由到相应的命令。
由于它提供松散耦合,因此使用数据绑定可减少不同类型的代码之间的硬依赖关系。 这样就可以更轻松地更改各个代码单元(方法、类、控件等),而不会在其他单元中造成意外的副作用。 这种分离是 关注点分离的一个例子,这是许多设计模式中的重要概念。
MVVM 的优点
分离代码有很多好处,包括:
- 采用迭代的探索性编码样式。 处于隔离状态的更改风险较小,更易于尝试。
- 简化单元测试。 相互隔离的代码单元可以单独在生产环境外部进行测试。
- 支持团队协作。 遵循设计良好的接口的分离代码可由单独的个人或团队开发,稍后集成。
- 提高可维护性。 修复分离代码中的 bug 不太可能在其他代码中导致回归。
与 MVVM 相比,具有更传统的“代码隐藏”结构的应用通常使用数据绑定来仅显示数据,并通过直接处理控件公开的事件来响应用户输入。 事件处理程序在后台代码文件中实现(如 MainWindow.xaml.cs),常常与控件紧密耦合,并通常包含直接操作 UI 的代码。 这使得无需更新事件处理代码就难以或不可能替换控件。 使用此体系结构,代码隐藏文件通常会累积与 UI 不直接相关的代码,例如数据库访问代码,这些代码最终会重复和修改,以便与其他窗口一起使用。
应用层
使用 MVVM 模式时,应用分为以下层:
- 模型层定义表示业务数据的类型。 这包括为核心应用域建模所需的所有内容,并且通常包括核心应用逻辑。 此层完全独立于视图和视图模型层,并且通常部分驻留在云中。 给定完全实现的模型层,可以选择创建多个不同的客户端应用,例如使用相同基础数据的 Windows 应用 SDK 和 Web 应用。
- 视图层使用 XAML 标记定义 UI。 标记包括定义特定 UI 组件与各种视图模型和模型成员之间的连接的数据绑定表达式(如 x:Bind)。 代码隐藏文件有时用作视图层的一部分,以包含自定义或作 UI 所需的其他代码,或者在调用执行工作的视图模型方法之前从事件处理程序参数中提取数据。
- 视图模型层为视图提供数据绑定目标。 在许多情况下,视图模型直接公开模型,或提供包装特定模型成员的成员。 视图模型还可以定义成员来跟踪与 UI 相关的数据,而不是与模型相关的数据,例如项列表的显示顺序。 视图模型还充当与其他服务(如数据访问代码)的集成点。 对于简单项目,可能不需要单独的模型层,但只需要封装所需所有数据的视图模型。
基本和高级 MVVM
与任何设计模式一样,实现 MVVM 的方法不止一种,许多不同的技术都被视为 MVVM 的一部分。 因此,有几个不同的第三方 MVVM 框架支持各种基于 XAML 的平台,包括 Windows 应用 SDK。 但是,这些框架通常包括多个用于实现分离体系结构的服务,使得 MVVM 的确切定义有些模糊。
尽管复杂的 MVVM 框架非常有用,尤其是对于企业规模项目,但通常会产生与采用任何特定模式或技术相关的成本,并且根据项目的规模和大小,这些优势并不总是清楚的。 幸运的是,你只能采用那些提供明确和有形优势的技术,并忽略其他人,直到你需要它们。
具体而言,只需了解和应用数据绑定的全部功能并将应用逻辑分离到前面所述的层中,即可获得很多好处。 这只能使用 Windows 应用 SDK 提供的功能,而无需使用任何外部框架来实现。 特别是 ,{x:Bind} 标记扩展 使数据绑定比在以前的 XAML 平台中执行得更容易、性能更高,因此不需要之前所需的大量样本代码。
有关使用基本 MVVM 的附加指南,请查看 GitHub 上的 Customers Orders Database UWP 示例 。 其他许多 UWP 应用示例 也使用基本的 MVVM 架构,交通应用 UWP 示例 包括代码隐藏和 MVVM 版本,并附有描述 MVVM 转换 的说明。