我对MVVM有着复杂的感受。似乎我需要编写大量代码才能使最基本的东西正常工作。我想念事件(命令是一件很麻烦的事情),将所有内容绑定导致调试困难,而且我想念对视图的引用!
我只是想知道你对MVVM和传统的代码方式有什么看法。你更喜欢哪种方式,或者你通常使用或建议使用哪种方式?
谢谢
我对MVVM有着复杂的感受。似乎我需要编写大量代码才能使最基本的东西正常工作。我想念事件(命令是一件很麻烦的事情),将所有内容绑定导致调试困难,而且我想念对视图的引用!
我只是想知道你对MVVM和传统的代码方式有什么看法。你更喜欢哪种方式,或者你通常使用或建议使用哪种方式?
谢谢
[2010年12月10日更新 - 微软最近宣布SL5将具有调试数据绑定的能力,包括在其上设置断点,以便您可以看到发生了什么。这是朝着正确方向迈出的重要一步。它仍然没有解决我认为的根本问题,即数据绑定没有编译时类型检查,但它大大提高了工具集的实用性。]
有人提到了测试,这是一个很好的观点。 在我看来,另一个观点是可重用性,将相同的视图模型绑定到不同的视图上。例如,您可能为某些用户提供简化的视图,而为其他用户提供更高级的视图。
我看到有人提到事件处理很麻烦之类的问题。有MVVM框架可以处理这个问题。在我看来,将事件处理程序挂钩到代码后台并从代码后台调用视图模型中的方法也是可以接受的。这肯定比因为难以挂钩事件而不使用MVVM要好得多。
另一个巨大的优势在于MVVM的本质,即GUI和业务逻辑的分离。如果您与设计师合作,他们都在XAML世界中,谈论渐变、边框、阴影等等。而您,程序员,可以愉快地编写ViewModel和单元测试。因此,当设计师准备好原型时,只需连接命令和绑定即可。轻松搞定GUI =)
我还喜欢的是,我可以对UI进行巨大的更改,而不必触及我的逻辑。或者,我可以轻松添加更多的逻辑,而不必触摸我的UI。例如,我已经从列表更改为组合框,并且没有必要触摸代码。
至于命令,这对我来说很难一段时间。然后我发现了MVVM Light中的RelayCommand。使用它非常简单地设置一个方法来触发命令。个人上几乎从不使用命令的参数选项。我更喜欢只在视图模型内部使用状态。
MVVM类似的方法的实用性随着应用程序的范围和复杂性而扩展。一端是“不太复杂,也不太有用”,另一端是“需要多年时间来构建,如果没有MVVM这样的东西就不可能”。
可测试性与此密切相关 - 对于足够小且足够简单以至于MVVM感觉过度的应用程序,真正的单元测试覆盖率也是荒谬的。然而,现实世界通常非常复杂,这意味着真实世界的应用程序需要单元测试来维护质量,并且它们需要MVVM来进行测试和管理。任何认为他们可以在没有它们的情况下完成工作的人都会浪费大量精力,而实际上只需要很少的精力;或者更糟糕的是,让严重的质量问题被其他事物掩盖。
除了WPF(和Silverlight 2)的功能使MVVM成为一种自然的应用程序结构方式之外,该模式也很受欢迎,因为ViewModel类易于进行单元测试。当应用程序的交互逻辑存在于一组ViewModel类中时,您可以轻松编写测试它的代码。从某种意义上说,视图和单元测试只是两种不同类型的ViewModel消费者。拥有一套应用程序ViewModel的测试提供免费且快速的回归测试,有助于降低维护应用程序的成本。
对我而言,这是使用MVVM最重要的原因。
以前,我会将视图和视图模型混合在一起。但是,视图本质上具有鼠标和键盘事件作为输入,并具有绘制像素作为输出。如何对此进行单元测试或集成测试?MVVM通过将不可测试的视图与可测试的视图模型分离,并尽可能保持视图层薄,从而解决了这个问题。
MVVM 有它的痛点 - 就像所有需要命令的样板代码、与绑定语法搞混以及需要愚蠢的 hack 来关闭表单。
-- 但是 --
这都是由于缺乏一个好的框架 - this video 对我来说是一个很大的启示,如果选择正确的框架,它可以自动处理所有恶心的部分(如果找不到好的框架,编写解决您痛点的迷你框架比处理“裸” MVVM 更容易)。
只需观看该视频,看看如何使用良好的小型框架编写 MVVM 应用程序所需的代码比替代方案少。