MVVM - 模式和实用性

时间:2015-08-12 09:32:45

标签: c# wpf mvvm

我已经在WPF上使用MVVM一段时间了。我在开发过程中学到了很多东西(从不使用它,到开发了几个应用程序)

然而,最近我对代码进行了一些评论,让我想知道我是否正确地做事。我当前的设置(大致)如下工作:

  • 模型 - 负责存储数据,使用数据验证 IDataErrorInfo和脏跟踪
  • ViewModel - 负责获取数据(来自像。的存储库) 模式)并格式化视图的消费(像 过滤,排序)也负责命令处理 查看(保存,加载,过滤更改等)
  • 查看 - 常用的UI内容

现在有人提到我应该从不在模型中有业务逻辑,并且模型应该尽可能薄,viewmodel应该负责处理诸如数据验证之类的事情和脏的跟踪。

我已经看到了对此双方的评论和批评,人们反对并在模型中加入逻辑,我还没有看到的是这些全面陈述的任何实际原因。所以我很想知道我是否应该重构我的设置。

另外,鉴于我确实将逻辑移动到viewmodel,我可以看到需要有多个viewmodel,其中我当前有一个,例如:

  • Person - 型号
  • PersonViewModel - 处理脏跟踪,数据验证等
  • PersonsViewModel - 处理获取PersonViewModel的集合, 过滤等
  • PersonsView - 用户界面

这似乎有点多余,但也许我误解了一些东西。我真正想要的是这样或那样做的一些实际原因,或者这是另一个论点,比如在MVVM中使用代码隐藏(纯粹的意见,没有什么理由等)

4 个答案:

答案 0 :(得分:3)

MVVM的高级描述:

  • 查看:用户界面

  • 模型:业务逻辑和数据(例如域模型+存储库,或事务脚本+ POCO实体等)

  • ViewModel :以这种形式展示的数据,可以从视图中轻松获取。维基百科的定义是:视图模型是公开属性和命令的视图的抽象。

我喜欢Practical MVVM Manifestoarchived version)原则:简洁,可混合性,可设计性,可测试性。

这是非常高级和抽象的描述,这就是为什么你可能会发现很多MVVM的变种。无论你选择什么样的mvvm风格,请记住责任和原则,你应该没问题。尽量避免复杂性。 MVVM不是一个银饰,你不能用单一设计模式覆盖所有场景。一个mvvm实现可能适用于一个应用程序但不适用于另一个应用程序。例如,我为每个新项目从头开始构建我的mvvm架构以确保最佳匹配

<小时/> 什么时候承担责任:

以验证为例: 密码和重复密码输入应该相等的验证逻辑显然是表示逻辑,应该存在于viewmodel中。另一方面,可能存在业务规则,该密码必须至少包含一个特殊字符。此逻辑应驻留在Model中,但是您可以在viewmodel中将其公开,以便从视图中轻松使用。这是一个商业逻辑,但您可能需要以某种方式呈现它。

如果您的应用程序仅使用webservice来检索和存储,那么您的模型可能只是数据访问组件。

<小时/> 这里有几个资源:

维基百科:https://en.wikipedia.org/wiki/Model_View_ViewModel

MVVM是Martin Fowler的MVP模式的变体,您可能会发现它也很有用:http://martinfowler.com/eaaDev/PresentationModel.html

MSDN(模式和实践):https://msdn.microsoft.com/en-us/library/hh848246.aspx

答案 1 :(得分:2)

我喜欢将模型层视为与托管应用程序的方式无关的任何内容(即独立于WPF)。它是一个或多个代表业务域的dll以及需要在其中执行的操作。如果采用相同的dll并在Web应用程序中使用它们是有意义的,那么Windows服务e.t.c通常表明Model和ViewModel之间的分割是合适的。

答案 2 :(得分:1)

您的问题没有简单的答案。最简单的答案是模型和视图模型应该包含您应该单元测试的代码。模型和视图模型之间的分离稍微不那么明显。我喜欢让模型尽可能简单,并将其限制为与服务器层交换的任何内容。视图模型应该封装模型,并提供任何附加功能(业务逻辑和抽象表示逻辑),以便您可以使表示层尽可能简单(声明,在WPF XAML的情况下)。

答案 3 :(得分:1)

我这样看:

模型 - 可以传递的对象。不同层之间的通用类型,用于通信。

ViewModel - 专门为视图创建。这应包含UI逻辑,例如,Data Annotations等将在此处。您也可以在这里调用您的Web服务方法(假设您的实际业务逻辑位于外观层,或者您的数据库逻辑位于不同的层/项目中)以填充视图,下拉菜单等。您可能最终会得到这些方法的倍数。视图,取决于您的设计。

查看 - 仅限用户界面。

我不害怕在ViewModel中放置外部调用