MVVM澄清:哪些内容属于ViewModel,哪些内容属于Model?

9

我最近重新研究了MVVM,发现有很多新的教程和指南。然而,大部分MVVM的例子都没有解释清楚一些我不太明白的东西。所有这些例子都相当简单,没有一个从数据库/文件等读取数据。

例如,我有一个类似于画图应用程序,并将绘画保存在XAML中。哪些内容属于ViewModel,哪些属于Model呢?

Model是否提供函数来加载/保存XAML文件中的绘画?

ViewModel是否绑定到Model公开的属性(颜色、宽度、位置等)?

验证是在Model还是在ViewModel中进行?

2个回答

2

ViewModel是适用于您正在使用的演示技术的模型表示。

在您的示例中,我认为Model不会提供从/到XAML文件加载/保存绘画的功能。这将由数据访问对象/存储库执行,ViewModel将以Model实例作为输入调用它们。这一部分通常是可变的,取决于您的Model类的外观。

ViewModel本身通常不使用数据绑定。它只是以对演示(View)技术有用的方式将Model公开给View。在WPF / Silverlight的情况下,这基本上意味着它实现了INotifyPropertyChanged接口。

验证通常由View启动(几乎所有内容都是如此),由ViewModel执行,但通常由ViewModel委托给Model。当然,最好不要在整个应用程序中重复验证。通用验证的最佳位置是Model(参考IDataErrorInfo)。但是,特定于ViewModel的验证可以直接在ViewModel中处理。


我认为有必要讨论将模型中发生的数据更改暴露给视图模型,以便通过正常数据绑定将其绑定和更新到视图。如果您考虑数据层,它将具有有关在维护该数据的过程中提取的数据状态的指标(特别是离线数据存储)。如果这些指标存在并且在模型层发生更改,那么您将如何从模型向视图模型推送更改通知以进行数据绑定到视图? - ScottCher

1
从一方面来看,ViewModel可以是Model对象的包装器,并扩展它的演示细节。例如,如果您有Model对象 - Pen,则PenViewModel可以包含IsSelected,IsDragging属性等。这是“ViewModel作为包装器”。
从另一方面来看,ViewModel可以是View上的抽象,不包含对特定控件的引用。不要忘记MVVM的一个目标是单元测试。因此,例如,您的绘画应用程序中有可拖动的条形图。因此,您可以使用一组ViewModels来抽象此功能:BarViewModel {IsSnapped,Position,IsEnabled},BrushBarViewModel:BarViewModel,PenBarViewModel等。然后,您可以使用单元测试覆盖此功能,但所有这些内容都与Model无关。这是“ViewModel作为View抽象”。
Model非常接近业务,包含业务实体和逻辑,用于持久化实体的类,服务。您可以在Model中使用不同的概念,例如DDD(领域驱动设计),Fawler的企业模式,CQRS(命令查询责任分离),SOA(面向服务的架构)。
View使用绑定机制(最坏情况下在PresentationModel模式中的代码后台)将状态与ViewModel(Model)同步。
基于此,你的问题的答案如下:

模型是否提供从/到XAML文件加载/保存绘画的功能?

不提供。模型没有直接引用任何XAML文件。

ViewModel是否绑定到模型公开的属性(颜色、宽度、位置等)?

不是。绑定是视图同步机制。因此,您需要将视图绑定到这些属性。您可以直接将视图绑定到模型或ViewModel包装器。

验证是在模型还是ViewModel中进行的?

随时。如果您的控件支持验证,则可以在视图层上进行验证,例如DateTimePicker不允许选择不正确的日期。您可以在ViewModel中编写自定义验证逻辑,并使用单元测试进行覆盖。此外,验证可以在模型级别进行,作为额外的检查,因为模型不能处于无效状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接