【问题标题】:Confustion in Concept of MVVMMVVM概念的混淆
【发布时间】:2014-02-12 02:51:37
【问题描述】:

我试图理解过去两周的MVVM,但仍然对理解它有很多困惑。

我最近开始了 Windows Phone 8 的开发。

我对MVVM的理解,

M = Model 表示数据,具体的意思是Model 应该被视为C 语言的struct。它只会有属性或成员变量(对象)。它对 View 和 View Model 一无所知。

V = 普通 XAML。应该只有一种绑定方式,那就是使用DataContext

VM = View Model 是视图模型。 VM 使用 M 来保存其数据(使用 Containership),VM 负责将数据保存在 DB 中或从 db 中获取数据。 DB 交互应该发生在 VM 中。 VM 应该实现INotifyPropertyChanged,因为它负责保存和获取数据。

请建议我对 MVVM 有错误的概念。

【问题讨论】:

  • DB interactions should happen in VM 我通常更喜欢将这种逻辑放在服务层中,这至少有两个好处:逻辑可以在所有虚拟机之间共享,并且可以让虚拟机集中注意力担任数据翻译角色。
  • 否则,我看不出您对 MVVM 的描述有什么问题。你能准确地说出让你感到困惑的地方吗?还要记住,对 MVVM 的不同解释与应用程序一样多。这就是为什么它被称为 pattern
  • @KooKiz 我的困惑是,1. 'modle' 是否应该被视为结构(概念上),2. VM 是否应该只实现 'INotifyPropertyChanged'
  • 最纯粹的可能是在Vm中只有INotifyPropertyChanged,在模型中实现它虽然可以节省很多代码。而且它不是特定于视图的,所以在模型中实现它是好的。
  • 我完全同意@Johan Larsson,INotifyPropertyChanged 必须在模型中,ViewModel 可以实现任何不违反 MVVM 原则的接口。在VM中最好留下IDataErrorInfo实现接口等。然而,你对 MVVM 的看法很好,我没有注意到缺陷。

标签: wpf xaml mvvm windows-phone-8 inotifypropertychanged


【解决方案1】:

您所说的一切在技术上都是正确的,但我会尝试以更抽象的方式处理设计模式,并考虑它试图解决的问题。 MVVM 正在尝试解决在视图和模型之间提供分离的问题以及提供双向绑定(即从模型中提取数据并呈现它,以及获取用户输入并保存它)回到模型)。

大多数模式都希望将 View 和 Model 分开,因此在 MVVM 中仍然是一样的,但更模糊的是如何转换/格式化数据以显示给用户,以及如何将用户输入转换为您的模型。在许多 MVC 框架中,模型数据在视图中的呈现处理得非常好,但您通常需要靠自己来获取用户输入并干净利落地转换回模型。 MVVM 旨在处理这两者。

Microsoft 已选择使用 DependencyProperty、ICommand 和 ValueConverters 等工具来实现这一点。基本思想是您的视图只会通过绑定松散地附加到视图模型,因此理论上您可以将视图模型与其他视图重用。这在另一个方向上是相同的(例如,这种干净的双向绑定使 MVVM 与 MVC 不同),因为您的 VM 可以通知属性已更改(这就是您必须实现 INotifyPropertyChanged 的​​原因),但 VM 有不知道是否有视图可以做出反应。当您想要重用这些组件时,这非常简单。

因此,了解 MS 试图用 MVVM 解决什么问题后,您有望更好地理解 INotifyPropertyChanged 之类的东西存在的原因或 ICommand 的用途,并希望能充分利用 MVVM 模式。

【讨论】:

    【解决方案2】:

    自 2008 年以来我一直在使用 MVVM,您的解释主要是我会向以前没有使用过 MVVM 或任何 MV* 模式的人解释的那样。

    正如 Michael 所说,核心是将视图与逻辑分开,因为所有 MV* 框架都旨在实现这一点,但实现方式略有不同。随着 WPF 的出现,XAML 将数据绑定提升到了一个全新的水平,现在我们可以绑定几乎任何东西,而无需直接依赖数据。

    在 MVC 中,我们有控制器“告诉”视图要做什么,而在 MVVM 中,视图监听 ViewModel 必须说的内容,例如。 ViewModel 的 IsDirty 属性指示数据已更改,然后视图有一种可视化方式。告诉视图做什么不是 ViewModels 的工作,它是监听 ViewModel 变化的视图。通过为输入控件绑定两种方式,这可以反过来工作。 ViewModel 不知道这些数据是怎么来的,它只规定它应该是什么类型。

    当我尝试解释用 MVVM 编写的更复杂的项目时,我将 ViewModel 分为两种不同的子类型; WrapperViewModels、LogicViewModels。

    • WrapperViewModel:这是一个 ViewModel,或多或少只是对模型的补充。它包含与 PropertyChanged 逻辑一起公开数据的属性。它包含用于公开的逻辑,例如。 FullName 当模型只有 FirstName 和 LastName 等时。但是,可以通过在模型中实现 INotifyPropertyChanged 来替换此 VM,但这可能不是所有情况下的最佳方法。

    • LogicViewModel:这些 VM 包含应用程序逻辑。作为应用程序核心的 MainViewModel 就是其中之一。如果您将应用程序视为一组岛,其中每个岛负责应用程序的一部分,这部分通常有自己的 LogicViewModel

    当谈到模型层时,我通常会说以下逻辑驻留在该层中;数据、数据库访问、服务访问、文件访问。基本上所有与应用程序之外的东西进出有关的代码。我不会在 ViewModel 中编写任何直接访问模型对象和其他 ViewModel 之外的任何东西的逻辑。

    在某些情况下,MVVM 往往会使一些简单的任务变得过于复杂。在这些情况下,我建议考虑从视图和视图模型中进行真正的控制。这样做可以重用控件并完全控制其内部。其他简化 MVVM 开发并且几乎是强制性的事情是信使/中介模式、依赖注入和行为/触发器/动作/附加属性的知识。

    大多数人说的事情是视图应该是纯 Xaml,没有逻辑。在我看来,这是完全错误的。只要遵循 View 不应该知道 ViewModel 逻辑的原则,View 中就允许代码/逻辑。由于逻辑纯粹是为了利用演示,所以它是可以的,但是一旦你引用了 ViewModel 类,你就如履薄冰。

    【讨论】:

      【解决方案3】:

      我倾向于将 MVVM 描述为 Model View Presenter 的发展。在 Model View Presenter 中,Presenter 获取模型并构建视图。改变模型,视图就会改变。 MVP 再简单不过了,这也是我从它开始的原因!

      ViewModel 是单向 Presenter 的替代品:它是状态跟踪的双向等效物。除了监视模型的变化,它还监视事件和视图的变化,并提供胶水和逻辑来更新模型系统。

      这是一个从技术细节中删除的更通用的答案,希望它在展示这个想法时能起到尊重的作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-30
        • 2019-06-17
        相关资源
        最近更新 更多