WPF/Silverlight程序员:MVVM模式是否过于繁琐?

7

我对MVVM有着复杂的感受。似乎我需要编写大量代码才能使最基本的东西正常工作。我想念事件(命令是一件很麻烦的事情),将所有内容绑定导致调试困难,而且我想念对视图的引用!

我只是想知道你对MVVM和传统的代码方式有什么看法。你更喜欢哪种方式,或者你通常使用或建议使用哪种方式?

谢谢

8个回答

7
我在这方面肯定是少数派,但我倾向于同意@Shnitzel的观点。MVVM及其绑定是很好的想法,但它们受到当前MS工具的支持不足。所有除最简单的绑定之外,其语法都很难正确使用,并且由于WPF和Silverlight会默默地吞噬所有错误,所以这使得语法更加困难。(是的,一些错误会出现在调试窗口中,但其中没有足够的详细信息。)你可以使用像编写调试值转换器这样的技巧,但事实仍然是,工具集仍然相当不成熟。(然后有我的标准抱怨,即数据绑定没有强类型,这意味着工具无法为您捕获错误。)
我听到每个人都坚持要进行测试,而且我是自动化测试的大粉丝。但至少在我们的工具状态目前的情况下,MVVM的改进的可测试性是以相当大的代价为代价的。
考虑这种情况:您有一个包含50多个表单/页面的大型应用程序,并且刚刚进行了Model和ViewModel的重大重构。在此过程中,您重命名了一堆类和属性等。现在找到您需要更改以反映新类和属性名称的XAML中的每个位置。那么测试性就这样了吗?IDE不仅无法捕获绑定错误,编译器也无法捕获它们,最重要的是,应用程序甚至不会在运行时抛出错误。您必须让测试人员运行整个应用程序,并确保所有绑定仍然按照您想要的方式执行。难受啊。至少在我还在老式方法时,编译器会告诉我当我拼错了某些东西。

[2010年12月10日更新 - 微软最近宣布SL5将具有调试数据绑定的能力,包括在其上设置断点,以便您可以看到发生了什么。这是朝着正确方向迈出的重要一步。它仍然没有解决我认为的根本问题,即数据绑定没有编译时类型检查,但它大大提高了工具集的实用性。]


实际上我非常喜欢WPF/Silverlight中的绑定引擎。我会在代码后台中使用绑定,所以这不仅仅是MVVM的事情。我的抱怨主要是不能轻松地调用视图对象上的方法。 - Shai UI
3
我认同我所概述的问题并不是MVVM模式固有的问题——而是我们在MS平台上可用的唯一工具和框架存在的问题 :-)在我孤独的看法中,根本问题是数据绑定没有强类型选项。一旦你打了“{Binding...}”,你就没有任何保障。在MS的假设中,图形用户界面和数据都很难处理,但将它们连接起来却很简单,因此你不需要任何工具支持来帮助你完成。这不仅是错误的,而且是极其荒谬的错误。 - Ken Smith
在我目前的Silverlight应用程序(约30K行代码)中,我们使用了一种模型-视图-控制器方法,而不是模型-视图-视图模型。它类似,但与Microsoft笨拙的绑定模型没有那么紧密地绑定。我们通过代码处理大多数UI更新,而不是绑定,正是因为绑定如此笨拙,难以正确实现,并且无法测试。然而,我们尝试在几乎所有内容周围添加接口,以便更轻松地混合和匹配各个部分。 - Ken Smith
绑定并不是让我感到烦恼的原因,而是一些简单的事情,比如尝试从视图模型运行故事板。当您没有对视图的引用时,这基本上是不可能的,除非进行某种类型的黑客操作。 - Shai UI
一些年后,Silverlight 已经死亡。 - GorillaApe
显示剩余3条评论

5

有人提到了测试,这是一个很好的观点。 在我看来,另一个观点是可重用性,将相同的视图模型绑定到不同的视图上。例如,您可能为某些用户提供简化的视图,而为其他用户提供更高级的视图。

我看到有人提到事件处理很麻烦之类的问题。有MVVM框架可以处理这个问题。在我看来,将事件处理程序挂钩到代码后台并从代码后台调用视图模型中的方法也是可以接受的。这肯定比因为难以挂钩事件而不使用MVVM要好得多。

另一个巨大的优势在于MVVM的本质,即GUI和业务逻辑的分离。如果您与设计师合作,他们都在XAML世界中,谈论渐变、边框、阴影等等。而您,程序员,可以愉快地编写ViewModel和单元测试。因此,当设计师准备好原型时,只需连接命令和绑定即可。轻松搞定GUI =)


使用相同的ViewModel在不同的视图中是非常实用的,可以节省很多时间。+1 - HCL

5
整个事情,以我个人看来,是一堆超级技术营销炒作,长远来看,除了将开发推向可以承受生产力损失的地方——即离岸外包,它将毫无意义。创建一个功能性UI的速度极其缓慢,而所有应用程序都被视为简单的内容页面、购物车或数据网格,这太糟糕了。所以,如果一个应用程序有一些错误需要在几个发布周期内纠正,那么我们就会用一个没有人能够理解整体情况的系统来换取什么呢?可测试性?真是一堆废话。好像错误和修复的日子已经过去了一样,对吧?没错,我的测试结果显示2+2=4,因此我的应用程序没有漏洞。不对吧。
迭代式开发会回来的,记住我的话。一旦与某些尽快需要的功能的生产相比,TDD的真实成本变得更加明显。

3
我认为你混淆了隐喻。我作为一个很小的团队的一员,我们建立了一个小型的MVVM库,进行了一些阅读并在良好实践方面互相教育。只要我们在处理新应用程序时注入了一点设计开销,它们就会很轻松地落地。如果你觉得在将代码塞进VS之前检查使用情况太困难了,那么请随意连接一些事件,在你的"spaghetti"代码中玩得开心,并好好对待winforms。它已经老旧且需要关爱。 - Gusdor

3
现在,有些人使用MVVM并且对此感到满意。但是,有些人不这样做,因为他们承担了大部分开发任务,而且没有与设计师、测试人员等人一起进行大型项目的开发。 然而,我曾经参与过两种方式的开发。有些人会采用任何模式并必须实现它,无论如何。 即使是用于管理一些小数据的小应用程序也被开发成MVVM和更多。它们将被安排和计划数周,即使其中一些程序可以在几天内完成,但必须满足模式、测试等要求。 老实说:许多开发人员通过实践学习,其中一些模式非常令人难以理解,因为它们结合了许多模式和抽象编程技术。

2
事实上,许多人不使用单元测试。但是,仍然有充分的理由使用MVVM。我想指出的是,这将业务逻辑与UI分开。此外,如果您有类似的视图,可以为它们使用相同的视图模型。

我还喜欢的是,我可以对UI进行巨大的更改,而不必触及我的逻辑。或者,我可以轻松添加更多的逻辑,而不必触摸我的UI。例如,我已经从列表更改为组合框,并且没有必要触摸代码。

至于命令,这对我来说很难一段时间。然后我发现了MVVM Light中的RelayCommand。使用它非常简单地设置一个方法来触发命令。个人上几乎从不使用命令的参数选项。我更喜欢只在视图模型内部使用状态。


1

MVVM类似的方法的实用性随着应用程序的范围和复杂性而扩展。一端是“不太复杂,也不太有用”,另一端是“需要多年时间来构建,如果没有MVVM这样的东西就不可能”。

可测试性与此密切相关 - 对于足够小且足够简单以至于MVVM感觉过度的应用程序,真正的单元测试覆盖率也是荒谬的。然而,现实世界通常非常复杂,这意味着真实世界的应用程序需要单元测试来维护质量,并且它们需要MVVM来进行测试和管理。任何认为他们可以在没有它们的情况下完成工作的人都会浪费大量精力,而实际上只需要很少的精力;或者更糟糕的是,让严重的质量问题被其他事物掩盖。


0

来自Josh Smith关于MVVM的文章

除了WPF(和Silverlight 2)的功能使MVVM成为一种自然的应用程序结构方式之外,该模式也很受欢迎,因为ViewModel类易于进行单元测试。当应用程序的交互逻辑存在于一组ViewModel类中时,您可以轻松编写测试它的代码。从某种意义上说,视图和单元测试只是两种不同类型的ViewModel消费者。拥有一套应用程序ViewModel的测试提供免费且快速的回归测试,有助于降低维护应用程序的成本。

对我而言,这是使用MVVM最重要的原因。

以前,我会将视图和视图模型混合在一起。但是,视图本质上具有鼠标和键盘事件作为输入,并具有绘制像素作为输出。如何对此进行单元测试或集成测试?MVVM通过将不可测试的视图与可测试的视图模型分离,并尽可能保持视图层薄,从而解决了这个问题。


0

MVVM 有它的痛点 - 就像所有需要命令的样板代码、与绑定语法搞混以及需要愚蠢的 hack 来关闭表单。

-- 但是 --

这都是由于缺乏一个好的框架 - this video 对我来说是一个很大的启示,如果选择正确的框架,它可以自动处理所有恶心的部分(如果找不到好的框架,编写解决您痛点的迷你框架比处理“裸” MVVM 更容易)。

只需观看该视频,看看如何使用良好的小型框架编写 MVVM 应用程序所需的代码比替代方案少。


看起来你的链接已经失效了。我认为这个链接是指向同一个地方的。 - Joshua Shearer

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