Эта статья MSDN нарушает MVVM? - PullRequest
4 голосов
/ 21 марта 2010

Это могут быть старые новости, но в марте 2009 г. в этой статье « Model-View-ViewModel в приложениях Silverlight 2 » был приведен пример кода, включающий 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

Что подразумевает этот класс, так это то, что разработчик намерен связать визуальные элементы напрямую с данными (да, используется ViewModel, но он определяет ObservableCollection объектов данных). Не слишком ли отличается этот дизайн от руководства MVVM? Теперь я вижу некоторые причины, почему мы должны идти по этому пути: то, что мы можем сделать с DataServiceEntityBase, - это такая вещь (которая близка к Entity Framework):

// 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 можно рассматривать как «игрушечный код» в образовательных целях, но кто-нибудь делает что-то подобное в мире 1011 * real разработки Silverlight?

Ответы [ 2 ]

6 голосов
/ 22 марта 2010

Чтобы сделать представление полностью независимым от модели, вам необходимо воспроизвести типы, которые во многих случаях идентичны типам модели в вашей модели представления.

* ** 1003 тысяча два * Пример

Модель содержит тип Person, обладающий свойствами FirstName и LastName. Визуальный дизайн требует «Список людей», поэтому существует представление, содержащее ListBox, который имеет привязку шаблона данных к путям свойств FirstName и LastName. ItemsSource привязывается к свойству ViewModel, которое предоставляет набор экземпляров типов, имеющих свойства FirstName и LastName.

Итак, вот вопрос, должна ли быть "версия ViewModel" типа Model Person или ViewModel просто повторно использует существующий тип Person из Модели?

В любом случае вполне возможно, что вы захотите, чтобы свойства были наблюдаемыми.

Для рассмотрения

Какие цели стоят за MVVM? Довольно часто мы хотели бы представить хорошие длинные списки того, почему шаблон существует, но в этом случае на самом деле есть только 2.

  • Отделяйте визуальный дизайн ( примечание : не дизайн) от кода.
  • Максимизируйте тестируемую поверхность всего приложения.

Предоставление типов моделей в ViewModel не является препятствием ни для одной из вышеуказанных целей. Фактически это помогает тестируемости, так как число типов и членов, которые нуждаются в тестировании, сокращено.

По моему мнению, я не вижу, чтобы реализация INotifyPropertyChanged подразумевала привязку к визуальным элементам. Могут быть и другие причины, по которым некоторые службы могут захотеть наблюдать изменения в свойствах модельного объекта.

Ключевой принцип отделения модели от представления заключается в том, чтобы скрыть любые подробности о том, как представление представляет модель из самой модели. Добавление свойства ForenameBackColor к модели, вероятно, было бы плохо. Вот где приходит ViewModel.

Итог

Требование, чтобы Модель выставляла наблюдаемые свойства, не является нарушением MVVM, это простое и общее требование, которое не требует, чтобы Модель обладала какими-либо конкретными знаниями о каком-либо Представлении или действительно, что вообще существуют какие-либо «визуалы».

3 голосов
/ 22 марта 2010

Нет, выглядит нормально для меня - DataServiceEntityBase - это просто имя его базового класса, от которого наследуются все его / бизнес-объекты DTO, ничего плохого в этой настройке (это имя вас немного смутило?) , Если он помещает свои данные в ViewModel, а затем связывает его View с виртуальной машиной, то, по крайней мере, у вас есть часть MVM MVM.

Главное, что меня огорчило бы, это то, что он назвал метод FirePropertyChanged - лично я бы назвал его On PropertyChanged.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...