WPF综合指南:MVVM与MVP

时间:2009-05-08 10:01:17

标签: wpf design-patterns mvvm mvp prism

我很困惑。也许你可以帮助我:)。

我一直遵循CAG的指导,发现MVP模式对我来说非常自然。 假设我有一个支持UI的模型(例如:实现INotifyPropertyChanged),我使用演示者将此模型绑定到视图(演示者知道视图的接口),保持我的Code-Behind尽可能小只处理Bindings(模型和命令)属性(或方法)或没有ICommand的控件的事件,在这种情况下立即被委托给演示者。

  1. 过了一段时间,我发现了MVVM模式,到目前为止它还没有找到我。 据我所知,只有当我的模型不支持UI时,我才会使用MVVM。但是保持演示者并使用新模型更合理,我无法理解这种用法​​会让我失去什么。 我知道我错过了什么,但它是什么:)。

  2. 此外,当您的View是通用的并且可以处理多种模型时(例如在PropertyGrid中)。建议将ViewModel与DataTemplate一起使用,但在这种情况下,您无法为模型中的每个实体创建模板,只需要在运行时进行调查,您会推荐什么?

  3. 在观看Josh Smith在screencast中讨论MVVM的过程中,我感觉到ViewModel中模型的重新暴露违反了DRY(不要重复自己),这真的是不可避免的吗?在火焰ADO.Net Dynamic Data metadata classes are getting nowadays的比较中,没有人对他的争论感到惊讶。

  4. 希望它足够清楚

    由于

    爱丽儿

4 个答案:

答案 0 :(得分:20)

关于#3,很多人会使用“另一层间接”参数,说模型中的更改不会影响视图。虽然这在技术上是正确的,但这并不是做这样的事情的真正原因。

如果您将模型视为从数据访问层或服务(这通常被认为是这些)返回的实体,您就会开始了解为什么需要ViewModel。 ViewModel旨在 使用View所需的行为扩展模型

例如。如果您希望能够更改属性并通过绑定通知View此更改,则该属性需要引发某种形式的NotifyPropertyChanged以便视图可以做出反应。这是典型模型不具备的行为。

在另一个示例中,假设您有一个集合,并且当用户单击视图中该项旁边的复选标记时,您希望使用布尔值标记集合中的每个项。你可能需要一个“IsSelected”属性。这是模型不应该提供的行为。

但是我知道你来自哪里......我一开始确实遇到了这个问题。我第一次将模型的内容复制并粘贴到我的视图模型中时,我的胃转了一下,但你只需要为了使你的View工作,它需要这个额外的行为,而模型不应该不提供。

无论这有多么糟糕,强制你的WCF类型或LINQ to SQL类型(或你喜欢的ORM是什么)实现INotifyProperyChanged更糟糕。

答案 1 :(得分:6)

Ad.3。看起来你可能通过在ViewModel中公开Model来重复自己,但你真正做的是抽象模型,以便View只知道这个抽象(View只知道ViewModel)。

这是因为对Model的更改不应该破坏View。此外,您的模型可以实现为从不同来源获取数据的许多不同服务。在这种情况下,您不希望View了解所有这些,因此您创建了另一个抽象 - ViewModel。

答案 2 :(得分:6)

除上述评论外。我想分享一下我对差异的一些个人理解。

通常在MVP中你有View的界面,例如。 IView,用于抽象实际视图并将数据绑定到那些实际视图。相反,在MVVM中,您通常使用实际视图的DataContext,例如。一个XAML用户控件,用于进行数据绑定,类似于MVP中的IView。因此,假设不准确,两种模式的绑定类似。

主要区别在于Presenter与ViewModel部分。视图模型与演示者非常不同,演示者是在UI和模型之间交换数据的桥梁。实际上,就其名称而言,它是视图的模型。 ViewModel中公开的数据主要用于UI进程。因此,根据我的理解,在MVVM中,ViewModel是视图的抽象。与此相反,MVP主要使用IView来抽象视图。所以通常MVVM中的层数比MVP少,因此您可以编写更少的代码来在MVVM中执行相同的工作:

MVVM:Model - ViewModel(代表实际视图,即UI) - 实际视图

MVP:模型 - Presenter(用于在模型和UI之间交换数据的桥梁) - IView(代表实际视图,即UI) - 实际视图

MVVM相对于MVP的优势主要基于Microsoft产品中的以下两个强大功能,

  1. 指挥WPF。虽然已经有一些实现不在Silverlight运行时

  2. ,但它在未来可能在Silverlight中可用。
  3. WPF和Silverlight中的DataContext。

答案 3 :(得分:5)

如果演示者知道视图的界面,则您需要演示者使用的所有视图具有相同的界面或为每个视图制作演示者。使用MVVM,视图可以识别viewModel,并且viewModel知道模型(但反之亦然)。这意味着多个视图可以使用VM,多个VM可以使用模型。

我不太确定你在第二点要问的是什么。 VM不是View(或者知道Views),而对我来说DataTemplate定义了对象的显示方式。我把我的DataTemplates放在一个绝对属于View的ResourceDictionary中。我的VM层中唯一的WPF“东西”是命令。

我需要更多信息来回答你的第3点。如果你深入研究MVVM,也许它会自行解决。

Here's a related post of mine which might help you

祝你好运。