MVVM,我应该把逻辑放在模型还是视图模型(控制器)中?

3

我对MVVM模式还不熟悉,在一项Silverlight项目中进行一些MVVM重构工作,假设它是一个书籍购物应用程序。

View是一个书籍列表,我将书籍的标题绑定到ViewModel。因此,在ViewModel中有一个public string Title { get; set; },在Model中也有一个public string Title { get; set; }(我是对的吗?)

现在我想添加一个事件处理程序来更新书籍标题,我应该将事件处理程序放在ViewModel中还是放在Model中?Model的用途是什么?

2个回答

9
在我看来,“也不...”将控制器类添加到MVVM中。在视图模型中放置控制器代码的问题在于,它使其难以独立测试。在很多方面,我认为这和代码后台一样糟糕。
在我看来,每个人都认为MVVM没有控制器,因为他们省略了C。MVVM实际上是MVC的一个变体“只是添加了ViewModels”。
也许应该称之为MVCVM?
ViewModels仅用于卸载视图的“GUI”代码并包含任何绑定数据。ViewModels不应进行任何处理。一个好的测试是,您的ViewModel可以通过自动化单元测试进行测试,并且不依赖于数据源等。它们不应知道数据实际来自哪里(或者是谁在显示它)。
虽然它可能被忽视/避免,但控制器应负责决定在哪些视图中显示什么数据模型。ViewModel是Models(MVVM中的M)和Views之间的桥梁。这允许更简单的“分离”XAML创作。
我们在所有最近的项目中成功使用的模式是仅在模块中注册控制器,并在启动时初始化它们。控制器非常轻/薄,唯一需要挂起的东西就是监听或发送消息的生活。在其初始化方法中,它们注册任何需要拥有的内容(视图和视图模型等)。这种轻量级逻辑-仅内存模式也使应用程序更加轻巧(例如,对于WP7更好)。
我们遵循的基本规则是:
- 控制器根据事件做出决策 - 控制器获取数据并将其放置在适当的ViewModel属性中 - 控制器设置View Models的ICommand属性以拦截事件 - 控制器使视图出现(如果没有其他地方暗示) - 视图模型是“愚蠢的”。他们仅保存绑定数据,不做其他事情 - 视图知道它们显示某些形状的数据,但不知道它来自哪里
最后两点是您永远不应打破的规则,否则关注点分离就会消失。

关于将事件处理或逻辑放在ViewModel中的争论可能会存在,但现在我想知道Model专门用于什么?它不应该有逻辑,对吧? - demaxSH
该模型持有业务数据(通常也包括业务逻辑,但不包含UI或应用逻辑)。模型不应了解其使用方式。 Translated text: 模型持有业务数据(通常还包括业务逻辑,但从不包含UI或应用程序逻辑)。模型不应知道它如何被使用。 - iCollect.it Ltd
在MVVM中(这个还存在吗?),不应该需要控制器。视图直接绑定到ViewModel上。ViewModel提供了对“实际”模型的抽象。通常在控制器中执行的任何操作都应该在ViewModel(数据抽象)或视图本身(动作和交互)中完成。 - Kirk Broadhurst
@KirkBroadhurst:虽然这是可能的,但这恰恰与我建议的更好方法完全相反。您的建议是非常普遍的情况,但更难测试,并且将代码紧密耦合到演示或数据模型中。 - iCollect.it Ltd

2
简单来说,Model是“真实”的底层数据模型,包含应用程序可能需要的书籍列表的所有信息,并能够从数据库中获取和设置数据。
ViewModel是一个对象,主要存在于为您的View提供数据绑定。它可能是Model的子集,也可能将多个Models的属性组合成一个单一的对象。它应该包含必要和充分的属性,以使View能够完成其工作。
如果事件处理程序涉及到View,则应该放在ViewModel中。如果符合您的目的,可以尝试使用命令模式(参见Custom WPF command pattern example)。

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