.net - 始终在WPF应用程序中使用MVVM,或者替代模式仍然实用/有用吗?

标签 .net wpf design-patterns mvvm mvp

Microsoft .NET Architecting Applications for the Enterprise书的第374页上,有一张图表,介绍了表示层模式的演变及其对平台的影响(图7-14)。

该图表除了显示从原始MVC模式到更现代的变体的演变之外,还显示了以下现代模式可以应用于以下技术:

  • Model2 (MVC)
  • Web仅
  • 被动查看(MVP)
  • 网站
  • WinForms
  • WPF
  • 监督 Controller (MVP)
  • 网站
  • WinForms
  • WPF
  • MVVM (演示模型)
  • 仅WPF

  • 注意: Presenter First (MVP)是最近未出现在该图表中的另一种近期关注模式,它被设想为更适合TDD。

    据我了解,如果使用WPF进行开发,则MVVM模式是事实上的选择(类似于Model2的Web开发)。也就是说,似乎没有什么阻止人们在WPF应用程序中使用Passive View,Supervising Controller或Presenter First。这种方法将导致应用程序实际上并不关心前端是WPF,WinForms还是Web。这些MVP变体似乎提供了更大的灵活性。

    但是,是否要获得与UI平台无关的灵活性(可能不需要),是以牺牲WPF开发难度和失去WPF提供的部分功能/功能为代价的?如此之多以至于成本超过 yield ?

    换句话说,MVVM如此强大,以至于不应该在WPF应用程序中考虑其他替代方案吗?

    最佳答案

    @RS Conley的答案涵盖了这个主题,我同意大多数人的观点。我唯一不同的是在底线。

    MVVM是WPF中95%应用程序的架构。

    选择任何其他体系结构意味着要解决一些事情,而这些事情要比您能得到的最好的解决方案少。在RS Conley的情况下,“被动 View ”可能是最好的选择,但这与正常情况相比

    作为了解MVVM更好的一种方式,让我们看看他采用PassiveView方法时正在失去什么。

    可维护性

    在被动 View 中,ViewModel知道IView,这意味着不保留SRP(单一职责原理)。 PassiveView中的Controller与Model和View直接交互,因此正在做两项完全不同的事情!

    在MVVM下,作为应用程序核心的ViewModel仅需关注一个问题,即包含应用程序的状态和逻辑。这样的代码的可维护性确实比PassiveView,MVP或MVC更好。

    的确,PassiveView在自动化测试涵盖方面更好,但是恕我直言,良好的代码可维护性更为重要。
    可测试性可以帮助您确保您不会破坏代码,而可维护性则可以帮助您避免构建有问题的代码。

    在可维护性方面,MVVM和PresentationModel是对以前的UI架构的一种改进,这是因为SRP原则得到了严格遵守。在MVVM中编写足够的代码,您将明白我的意思。

    可混合性

    MVVM真正强大的另一个功能是可混合性。
    由于所有应用程序状态都保留在ViewModel中,因此很容易在设计时伪造数据,这极大地提高了生产率。
    这不可能在PassiveView,MVP或MVC中创建,因为在所有这些体系结构中, Controller 都必须主动将数据放入 View 中。在MVVM中,数据只是“跳转”到 View ,因此可以被模拟。

    可测试性

    这确实是PassiveView优于MVVM的地方。如果UI的100%单元测试覆盖率对您至关重要,那么这很重要。
    但是,在大多数情况下,MVVM所具有的覆盖范围已绰绰有余,并且您通常会使用常规的UI测试来添加另一层测试(最后还要在PassiveView中进行测试)。

    我认为可测试性在这三个功能中不太重要。按重要性排序,包括可维护性,可混合性和可测试性。

    MVVM在哪里不合适?

    去年,我参加了〜15个WPF和Silverlight项目,所有这些都非常适合MVVM。我认为在演示逻辑非常大的地方,例如在游戏中,MVVM可能不是正确的选择。
    除了游戏之外,除了提到RS Conley之类的特殊情况外,我真的想不出最适合MVVM的应用类别。

    关于.net - 始终在WPF应用程序中使用MVVM,或者替代模式仍然实用/有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5170633/

    相关文章:

    python - 在 Python 中处理灵活的函数参数

    .net - 如何同时使用两个数据库并在两个不同位置同时更新

    c# - 使用 RandomNumberGenerator 时出错,没有创建函数

    c++ - 使用 GetFieldProps 获取类的属性值

    c# - WPF MVVM 后台打印数据绑定(bind)问题

    c# - 如何将 Window 作为参数传递给 WPF C# 中的另一个类

    wpf - 带导航的ICommand

    c# - 避免在主窗体顶部使用全局变量的良好设计模式是什么?

    c# - 当 Http 请求发生实际下载时

    javascript - 对如何使用模块模式的困惑