为什么要使用MVVM?它有哪些核心优势?

40

为什么在处理 WPF 时我们选择 MVVM 而不是 MVC 或 MVP?

使用 MVVM 会带来哪些额外的好处?

编辑:

老实说,今天我参加了一次面试,被问到了这个问题。我回答了 INotifyPropertyChanged,ICommand,IValue Convertor 等等,但他并不满意。因此我提出了这个问题。

提前感谢。


3
我一直将MVVM视为MVC的一种变体。 - Matthew Groves
6个回答

53

我向您介绍一段由Jason Dolinger制作的特别有用的视频

从WinForms世界过来,实现任何MVX风格的模式似乎比它值得的麻烦多了,但是在现在使用WPF工作了几年之后,我可以诚实地说,我不会考虑任何低于这个标准的东西。整个范式都支持开箱即用。

首先,关键的好处是在viewmodel之间实现真正的分离。在实际操作中,这意味着如果/当你的model需要变化时,视图不需要改变,反之亦然。

其次,虽然你的model可能包含在视图中所需的所有数据,但你可能希望以这样一种方式抽象化这些数据,使得model不支持。例如,假设你的model包含一个日期属性。在该model中,它可以仅存在为DateTime对象,但是视图可能想要以完全不同的方式呈现它。如果没有viewmodel,你要么必须在model中复制该属性以支持视图,要么修改该属性,这可能会严重混淆“model”。

你还可以使用一个viewmodel来聚合你模型中存在于不同类/库中的部分,以促进更流畅的view接口处理。很不可能您希望以与用户相同的方式处理数据或者希望以相同的方式呈现数据。

除此之外,你还获得了在viewviewmodel之间自动双向数据绑定的支持。

实际上,我可以谈论很多额外的东西,但是Jason表达得比我好,所以我的建议是观看视频。几天后,你会想知道你以前怎么能没有它。

祝你好运。


5
这个由Jason制作的视频是我所见过/阅读过的最好的MVVM介绍。源代码可以在这里找到:http://blog.lab49.com/archives/2689 - Michael Olesen

19

以下是特定于MVVM的优点:

  1. 提高了视图的“可混合性”(即使用Expression Blend设计视图的能力)。这使得团队中拥有设计师和程序员的人可以各自独立地工作,实现责任的分离。
  2. 无外观视图逻辑。视图与其背后运行的代码没有关联,可以使相同的视图逻辑在多个视图之间重复使用或轻松更改或替换视图。将“行为”和“样式”分离。
  3. 无需更新视图的重复代码。在代码后台中,您会看到到处都是“myLabel.Text = newValue”的调用。使用MVVM,只需设置基础属性及其所有视图副作用,就可以确保视图适当地更新。
  4. 可测试性。由于逻辑完全不涉及视图(没有“myLabel.Text”引用),因此单元测试变得容易。您可以测试ViewModel的行为而不涉及其视图。这也使得以测试驱动开发视图行为几乎不可能使用代码后台。

另外两种模式实际上是针对解决的问题而分开的。您可以使用MVVM与MVP和MVC(大多数好的示例都会使用某种形式的这种结构)。

实际上,在我看来,MVP(使用被动视图而不是监控控制器)只是MVVM的一种变体。


2
2和4同样适用于MVC、MVP以及MVVM。 - Jeremy Roberts
是的...我忽略了那些模式,因为它们实际上涉及到典型应用程序的不同方面。我已经编辑了我的答案来包括这一点。 - Anderson Imes

5

WPF拥有比其他任何UI框架更好的数据绑定功能,MVVM没有这个功能会变得难以控制。

MVVM提供了单元测试和优秀的视图无关性,使其成为一个不错的使用选择。


3

内置支持ICommand和INotifyPropertyChanged是最大的优点。使用MVVM模式可轻松将命令与WPF UI连接并插入数据。一切都很顺畅。


说实话,今天我参加了一次面试,被问到了这个问题。我回答了类似于INotifyPropertyChanged、ICommand、IValue Convertor的东西,但他并不满意。因此我提出了这个问题。 - priyanka.sarkar

1

我个人认为MVVM不是一种好处,而是一种义务,对于那些想要使用WPF酷炫功能的人来说。

WPF非常重视数据绑定,以实现UI与模型的分离。但是,在WPF中技术上完成数据绑定的方式有些特殊,因为它与类(如DependencyProperty、INotifyPropertyChanged和ObservableCollection)紧密相连。

  • 由于这个原因,您不能像使用标准.NET技术那样随意编写模型。例如,WPF TreeView几乎不可能在不使用数据绑定和模板的情况下使用。您无法像在Winforms中那样简单地填充它。必须使用ObservableCollection将其绑定到分层模型,以表示节点的子项。

所以,假设V代表XAML代码及其代码后台(因此它与WPF作为技术相关联),而M代表您的模型(因此它与WPF UI技术没有任何关系)。

那么,在WPF下,只有这些V和M,您永远无法使其正常工作。

在这两个之间,您必须添加一些东西。一些WPF兼容并且理解您的模型的东西。一些能够处理DependencyProperty、ObservableCollection和INotifyPropertyChanged的东西。这就是所谓的VM。

另外,MVVM的替代方案是使用V&M(没有VM管道)与M兼容WPF,但仍具有合理的UI独立性的组合。从历史上看,ObservableCollection在WindowsBase.dll程序集中(随WPF一起发布),因此将通用模型绑定到与UI技术相关联的对象似乎非常奇怪。它已经移回到System.dll中。即使如此,有时候也很难保持一个纯粹的VM模型,而不对M进行特定于WPF的调整...


我同意你所说的大部分内容,但是WPF的数据绑定在代码后台和VM中都非常出色。即使没有MVVM,OC、INPC和DP也能够很好地工作。WPF真正的强大之处在于数据绑定而不是MVVM。我们同时构建MVVM和代码后台,两者都具有出色的数据绑定。 - tinmac

0

XAML 代码的数据绑定能力以及触发器的存在将会破坏 MVP 和 MVC 模式。


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