代码之家  ›  专栏  ›  技术社区  ›  rasx

这篇msdn文章是否违反了mvvm?

  •  4
  • rasx  · 技术社区  · 14 年前

    这可能是个老新闻,但在2009年3月,这篇文章 Model-View-ViewModel In Silverlight 2 Apps ,的代码示例包括 DataServiceEntityBase :

    // COPIED FROM SILVERLIGHTCONTRIB Project for simplicity
    
    /// <summary>
    /// Base class for DataService Data Contract classes to implement 
    /// base functionality that is needed like INotifyPropertyChanged.  
    /// Add the base class in the partial class to add the implementation.
    /// </summary>
    public abstract class DataServiceEntityBase : INotifyPropertyChanged
    {
    /// <summary>
    /// The handler for the registrants of the interface's event 
    /// </summary>
    PropertyChangedEventHandler _propertyChangedHandler;
    
    /// <summary>
    /// Allow inheritors to fire the event more simply.
    /// </summary>
    /// <param name="propertyName"></param>
    protected void FirePropertyChanged(string propertyName)
    {
      if (_propertyChangedHandler != null)
      {
        _propertyChangedHandler(this, new PropertyChangedEventArgs(propertyName));
      }
    }
    
    #region INotifyPropertyChanged Members
    /// <summary>
    /// The interface used to notify changes on the entity.
    /// </summary>
    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
      add
      {
        _propertyChangedHandler += value;
      }
      remove
      {
        _propertyChangedHandler -= value;
      }
    }
    #endregion
    

    这个类意味着开发人员 打算 绑定视觉效果 直接地 to data(是的,使用了viewmodel,但是它定义了 ObservableCollection 数据对象)。这种设计是否偏离了mvvm的指导?现在我明白了为什么我们要这样做的一些原因:我们能做什么 数据服务实体库 这类事情(与实体框架密切相关)是吗?

    // Partial Method to support the INotifyPropertyChanged interface
    public partial class Game : DataServiceEntityBase
    {
        #region Partial Method INotifyPropertyChanged Implementation
        // Override the Changed partial methods to implement the 
        // INotifyPropertyChanged interface
    
        // This helps with the Model implementation to be a mostly
        // DataBound implementation
    
        partial void OnDeveloperChanged() { base.FirePropertyChanged("Developer"); }
        partial void OnGenreChanged() { base.FirePropertyChanged("Genre"); }
        partial void OnListPriceChanged() { base.FirePropertyChanged("ListPrice"); }
        partial void OnListPriceCurrencyChanged() { base.FirePropertyChanged("ListPriceCurrency"); }
        partial void OnPlayerInfoChanged() { base.FirePropertyChanged("PlayerInfo"); }
        partial void OnProductDescriptionChanged() { base.FirePropertyChanged("ProductDescription"); }
        partial void OnProductIDChanged() { base.FirePropertyChanged("ProductID"); }
        partial void OnProductImageUrlChanged() { base.FirePropertyChanged("ProductImageUrl"); }
        partial void OnProductNameChanged() { base.FirePropertyChanged("ProductName"); }
        partial void OnProductTypeIDChanged() { base.FirePropertyChanged("ProductTypeID"); }
        partial void OnPublisherChanged() { base.FirePropertyChanged("Publisher"); }
        partial void OnRatingChanged() { base.FirePropertyChanged("Rating"); }
        partial void OnRatingUrlChanged() { base.FirePropertyChanged("RatingUrl"); }
        partial void OnReleaseDateChanged() { base.FirePropertyChanged("ReleaseDate"); }
        partial void OnSystemNameChanged() { base.FirePropertyChanged("SystemName"); }
        #endregion
    }
    

    当然,出于教育目的,msdn代码可以被看作是“玩具代码”,但是是否有人在 真实的 Silverlight开发的世界?

    2 回复  |  直到 14 年前
        1
  •  6
  •   AnthonyWJones    14 年前

    为了使视图完全独立于模型,您需要重新生成在许多情况下与view model中的模型类型相同的类型。

    例子

    模型包含 Person 类型有 FirstName LastName 财产。可视化设计需要一个“人员列表”,因此有一个包含列表框的视图,该列表框的数据模板绑定到 第一名字 姓氏 . 这个 ItemsSource 绑定到viewmodel的属性,该属性公开具有 第一名字 姓氏 财产。

    所以问题是, 是否应该有模型的“viewmodel版本” 键入或应将viewmodel简单地重新使用现有的 从模型中键入?

    在这两种情况下,您都很可能希望这些属性是可观察的。

    考虑

    MVVM背后的目标是什么?我们经常喜欢列出一个模式存在的原因,但是在这个例子中只有两个。

    • 独立视觉设计( 笔记 :不是设计)来自代码。
    • 最大化整个应用程序的可测试表面。

    在viewmodel上公开模型类型不会对上述任何一个目标构成障碍。事实上,它有助于测试性,因为需要测试的类型和成员的数量减少了。

    在我看来,实现inotifyproperty并没有改变 暗示 绑定到视觉效果。某些服务可能希望观察模型对象属性的更改,这可能有其他原因。

    模型与视图分离的关键原则是隐藏关于视图如何从模型本身呈现模型的任何细节。添加一个 ForenameBackColor 模型的属性可能不好。这就是viewmodel的来源。

    底线

    要求模型公开可观察的属性并没有违反mvvm,这是一个简单而一般的要求,不要求模型对任何视图有任何特定的知识,或者确实涉及到任何“视觉效果”。

        2
  •  3
  •   slugster Joey Cai    14 年前

    不,在我看来很好- 数据服务实体库 只是他所有DTO/业务对象继承自的基类的名称,这个设置没有什么问题(这个名称让您有点吃惊吗?)。如果他将数据放在viewmodel中,然后将其视图绑定到vm,那么您至少拥有mvvm的vvm部分。

    我最担心的是他的名字 防火性能改变 方法-我个人会称之为 财产发生了变化。