【问题标题】:Is MVVM pattern broken?MVVM 模式是否被破坏?
【发布时间】:2017-08-13 09:27:40
【问题描述】:

我有一个基于 MVVM 模式的 WPF 应用程序。一切正常。在 View-Model 的业务逻辑中,我需要调用一些对话框。我已经通过接口实现了它(接口实现在视图层中)。
对于对话框我需要设置父窗口,所以界面中的函数有一个参数“parentView”。

在我的 ViewModel 中,我有一个来自父窗口类型“对象”的属性“视图”。我将此属性作为实例化对话框的参数。

由于“View”-property 来自“object”类型,并且是从 View 层设置并转发回 View 层,因此 View-Model 层对 View 层没有依赖关系。

你怎么看,我破坏了 MVVM 模式吗?

【问题讨论】:

    标签: wpf mvvm architecture


    【解决方案1】:

    你怎么看,我破坏了 MVVM 模式吗?

    没有。视图模型不依赖于视图,它只知道您可以在单元测试中轻松模拟的接口。因此,只要“视图”只是某种事物的抽象,这并不会真正打破这种模式。

    出于类型安全的原因,您可能应该考虑将参数的类型从 object 更改为强类型接口类型。

    【讨论】:

    • 感谢您对类型安全的提示。这真的是我会考虑的。
    • types 之间的依赖关系是类级别(就架构而言的低级别)细节。在高级应用程序 component 设计(MVVM 的唯一关注点)上,模式被打破了。就 MVVM 而言,视图模型组件的唯一关注点是将模型组件(业务逻辑/域)呈现给充当接口的视图组件,用于解耦两个组件。
    • 由于经典应用程序是由人类使用的,经典应用程序反映了有目标的用户故事或用例。这些用例创建输入,由业务逻辑处理。业务逻辑返回一个结果,该结果是用户交互的目标,并实际显示给用户。业务逻辑的唯一目的是为用户故事服务。如果设计得当,视图模型组件应该不需要启动像显示对话框这样的操作来与用户交互。
    • 在设计应用程序时,视图模型不是用户,也没有用户故事:它永远不会主动询问或等待用户输入或触发业务逻辑它自己的兴趣(它没有兴趣,因为它是一个被动的演示者/架构界面)。将Window 替换为IWindowIDialogService 称为依赖倒置(一种类级模式或原则,例如,用于在单元测试中启用模拟),与MVVM(一种用于解耦组件/职责的组件级模式)无关.
    【解决方案2】:

    没有朋友 - 这是一个已解决的问题。 我的意思是所有解决方案都没有真正的美感,但您可以使用 Dialog-Service 例如。

    一个真正简单的实现是Singleton,它有一个带有你的Main-Window的静态字段。现在你可以从这个类中调用你的对话框了。

    我实际上认为 MahApps 是这样的,但他们以奇特的方式注册它:

    <controls:MetroWindow 
            x:Class="SomeMetroWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
            xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
            Dialog:DialogParticipation.Register="{Binding}"> <!-- watch this pls --->
    <!-- ... --->
    </controls:MetroWindow>
    

    这里是一个example 用于一般实现。这里还有一个arcticle 关于这个主题的文章。

    正如我所说 - 不是很漂亮,但解决了。

    【讨论】:

    • 嗨彼得,谢谢你的回答。实际上它适用于我的对话服务变体(更少的代码,更多的灵活性)。将父母放在单身对我来说不是一个解决方案(有时会有不同的父母)。
    • 一般而言,我不建议在WPF 中编写自己的DialogService,因为您采用的框架已经拥有最多的时间。而在 Windows-Store-Apps 中,已经有了“本机”解决方案。
    猜你喜欢
    • 2018-02-26
    • 2010-11-22
    • 2011-04-19
    • 2012-01-08
    • 2019-06-15
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多