【问题标题】:What do you do when you have Rich Models?当你有丰富的模型时你会做什么?
【发布时间】:2011-12-02 06:17:18
【问题描述】:

我正在处理一个项目中的现有代码,该项目到处都有丰富的模型(而不是 POCO)。基本上,有什么好的方法可以混合丰富的模型和ViewModels而不重复代码?


  • 丰富的模型具有数据验证。有什么简单的方法可以通过 ViewModel 重用这些?

例子:

public class PersonViewModel : INotifyPropertyChanged, IDataErrorInfo
{
    private Person _person;

    [Required] //This seems redundent...
    public String FirstName { ... }
}

public class Person
{
    [Required]
    public String FirstName { ... }
}

这只是一个例子......基本上,如果您有一个富模型,有没有办法在维护 MVVM 并避免冗余代码的同时利用它?我真的很想避免让我的模型成为任何数据上下文或被 ViewModel 完全公开。

例如:

public class PersonViewModel : INotifyPropertyChanged, IDataErrorInfo
{
    private Person _person;

    //This seems like a bad thing to do...
    public Person ThePerson { get { return _person; } }
}

【问题讨论】:

    标签: c# design-patterns mvvm viewmodel models


    【解决方案1】:

    这是一个经典的问题。

    如果您使用特定于表示层的接口和属性“污染”您的 Model 类,您会通过仅拥有任何逻辑模型的一个版本来提高效率,但会失去表示和业务模型独立发展的能力。

    如果您保持模型“纯”并维护一个单独的视图模型,您可以在每个模型中获得灵活性,但由于必须维护(并在两个版本之间映射)而降低效率。

    从理论的角度来看,对于更复杂的系统,我会推荐后者。如果您的系统相对简单(想想 CRUD),并且您不希望这两种类型的模型独立发展,那么使用前者可能相当安全。

    显然,这两种方法并不相互排斥,逐屏做出决定并非闻所未闻。

    【讨论】:

      【解决方案2】:

      MVVM 的一个想法是将表示层与数据层分开。这使您能够更改表示层正在使用的数据,而无需更改数据层的数据。

      因此,来自表示层的数据仅应用户请求写入您的数据层。您多余的 FirstName 属性用作图层边框,让您可以灵活地实现类似简单的“撤消所有更改”。

      考虑使用通用 ValueViewModel 来处理数据绑定所需的值更改通知。按照这种方法,您的视图模型将如下所示:

      public class PersonViewModel : INotifyPropertyChanged, IDataErrorInfo
      {
          private Person _person;
      
          [Required] //This seems redundent...
          public ValueViewModel<String> FirstName { ... }
      }
      

      使用此模式,您的模型不需要实现 INotifyPropertyChanged 接口,该接口再次将表示层与数据层分开。

      MVVM 是一种非常高大上的模式,你经常会看到第一眼看起来有点正式的东西,但遵循这种模式会给你很大的灵活性。如果您选择违反 MVVM 规则,您将把整个应用程序架构置于危险之中,因为这一违反会破坏您使用 mvvm 获得的灵活性。因此,如果您打算违反 MVVM,请考虑完全不使用它。

      【讨论】:

        【解决方案3】:

        我从未见过将整个模型从 ViewModel 暴露给 View 有什么问题。我知道这不是“MVVM-Purist”方法,但它简单、快速且效果很好。

        但我确实理解这两种方法同样有效,而且通常对于非常大的代码库来说,Model 和 ViewModel 之间的分离从长远来看会使生活更轻松。在这种情况下,为什么不让您的 ViewModel 验证返回您的 ModelValidation?它不如使用 DataAnnotations 漂亮,但您不会在多个位置创建验证。

        例如,我经常使用这样的东西:

        public string GetValidationError(string propertyName)
        {
            string s = null;
        
            switch (propertyName)
            {
                case "FirstName":
                case "LastName":
                    s = Person.GetValidationError(propertyName);
                    break;
            }
        
            return s;
        }
        
        string IDataErrorInfo.this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-05
          • 2010-12-11
          • 2010-12-23
          • 2010-09-30
          • 1970-01-01
          • 2010-11-08
          • 1970-01-01
          相关资源
          最近更新 更多