【问题标题】:MVVM: Thin ViewModels and Rich ModelsMVVM:精简视图模型和丰富模型
【发布时间】:2011-02-08 15:57:22
【问题描述】:

我继续与 MVVM 模式作斗争,并且在尝试为中小型项目创建实用设计时遇到了许多挑战。其中一个挑战是弄清楚如何在不创建大量重复、难以维护的代码的情况下获得与这种模式解耦的好处。

我目前的策略是创建“丰富的”模型类。他们完全意识到他们将被 MVVM 模式消耗并实现 INotifyPropertyChanged,允许观察他们的集合并保持认识到他们可能始终处于观察状态。我的 ViewModel 类往往很薄,仅在实际需要转换数据时才公开属性,它们的大部分代码都是 RelayCommand 处理程序。视图很乐意直接绑定到 ViewModel 或 Model,这取决于是否需要任何数据转换。我使用 AOP(通过 Postsharp)来缓解 INotifyPropertyChanged 带来的痛苦,以这种方式使我的所有模型类变得“丰富”变得很容易。

使用这种方法有明显的缺点吗?我是否可以假设 ViewModel 和 View 紧密耦合,以至于如果我需要对 View 进行新的数据转换,我可以根据需要简单地将其添加到 ViewModel 中?

【问题讨论】:

    标签: c# wpf mvvm model


    【解决方案1】:

    我认为你的模型上的 INotifyPropertyChanged 只有在你期望它同时被你的虚拟机和外部“力量”操作时才有用。

    我个人是 POCO 模型的支持者。将任何特定于框架的脚手架放入我的模型中都会让我担心。当您将事件放入模型类时,您必须仔细考虑模型生命周期、序列化、存储等可能存在的问题。例如,如果您从数据源重新创建对象并且旧的 INotifyPropertyChanged 订阅现在无效,会发生什么?

    同样,ObservableCollection 更好的地方是在 VM 中,它可以使用 IEnumerable 数据源,并且只向视图显示选定的或临时过滤的项目。

    【讨论】:

    • 外部“力量”很好地描述了我的设计目前的工作方式。我的虚拟机正在为视图转换模型(如有必要),但模型可能由虚拟机、其他模型或以不同方式与其交互的完全不同的虚拟机进行操作。如果工具扩展在我的模型中添加了连线,我希望我的所有虚拟机和视图都在观察连线以查看更改。我创建了监视模型 ObservableCollection 的自定义集合以提供特殊过滤(不仅仅是 CollectionView 过滤),但大多数时候我绑定到模型 ObservableCollection。
    【解决方案2】:

    我认为这是一种务实的方法——我们过去成功地遵循了这种模式。

    基本前提是直接绑定到为大多数只读数据实现 INotifyPropertyChanged 的​​模型,然后向视图模型添加额外的属性以查看需要转换的特定内容(如您所建议的那样)。对于非只读属性,我们发现创建视图模型条目(通常为字符串类型)是最简单的,因为这允许在视图模型中轻松添加客户端验证。

    【讨论】:

    • 你现在转换到不同的模式了吗?您是否从早期的方法中学到了一些具体的东西,表明需要改变您的方法?
    【解决方案3】:

    免责声明 - 我不是专家 -

    我没有将 INotifyChanged 放在我的模型上。起初我已经这样做了,但我很简单地意识到 INotifyChanged 实际上只适用于通知 UI,所以我现在只将 INotifyChanged 放在我的 ViewModels 上。这使得控制“RaisePropertyChanged”的数量变得更加容易......我的视图从不直接引用模型。

    我正在处理我的第一个 MVVM 项目,但正在进行我的第三次重大重构:P

    【讨论】:

      【解决方案4】:

      我同意 View 和 ViewModel 之间存在紧密耦合。但这可以通过尽可能使用 IValueConverters 进行转换在一定程度上得到缓解。

      我尝试将我的业务逻辑保留在我的 ViewModel 中。另外,我使用 Viewmodel 来改变我的 Model 的形状以适应 View 的预期。

      【讨论】:

        猜你喜欢
        • 2010-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-20
        相关资源
        最近更新 更多