MVVM: тонкие модели просмотра и богатые модели

Я продолжаю бороться с шаблоном MVVM и, пытаясь создать практический проект для малого/среднего проекта, столкнулся с рядом проблем. Одна из этих проблем состоит в том, чтобы выяснить, как получить преимущества развязки с помощью этого шаблона, не создавая много повторяющегося, трудноподдерживающегося кода.

Моя нынешняя стратегия заключалась в создании "богатых" моделей. Они полностью осознают, что они будут потребляться шаблоном MVVM и внедрять INotifyPropertyChanged, позволяют наблюдать их коллекции и оставаться осведомленными о том, что они всегда могут находиться под наблюдением. Мои классы ViewModel имеют тенденцию быть тонкими, но только раскрывают свойства, когда данные действительно должны быть преобразованы, причем основная часть их кода является обработчиками RelayCommand. Представления с удовольствием связывают либо с ViewModels, либо с моделями напрямую, в зависимости от того, требуется ли преобразование данных. Я использую AOP (через Postsharp), чтобы облегчить боль от INotifyPropertyChanged, что позволяет легко сделать все мои классы класса "богатыми".

Существуют ли существенные недостатки в использовании этого подхода? Могу ли я предположить, что ViewModel и View настолько тесно связаны, что, если мне нужно новое преобразование данных для представления, я могу просто добавить его в ViewModel по мере необходимости?

Ответ 1

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

Я лично сторонник моделей POCO. Включение каких-либо фреймворков в мою модель заставило бы меня беспокоиться. Когда вы помещаете событие в класс модели, вам необходимо тщательно рассмотреть возможные проблемы с жизненным циклом модели, сериализацией, хранением и т.д. Например, что произойдет, если вы воссоздаете свой объект из источника данных, а старые подписи INotifyPropertyChanged теперь недействительны?

Сходно лучшее место для ObservableCollection находится в виртуальной машине, которая может потреблять источник данных IEnumerable и отображать только выбранные или специальные фильтрованные элементы.

Ответ 2

Я считаю, что это прагматичный подход - мы успешно следили за этой моделью в прошлом.

Основная идея заключалась в непосредственном привязке к модели, которая реализует INotifyPropertyChanged для большинства данных только для чтения, а затем добавляет дополнительные свойства в viewmodel для просмотра конкретных вещей, которые необходимо преобразовать (как вы предположили). Для свойств, не доступных для чтения, было проще всего создавать записи в виде viewmodel (обычно из строки типа), так как это позволяет легко проверять проверку на стороне клиента в модели просмотра.

Ответ 3

Отказ от ответственности - я не эксперт -

Я не помещаю INotifyChanged в свои модели. Сначала я сделал это, но пришел к простому пониманию того, что INotifyChanged действительно практичен только для уведомления пользовательского интерфейса, поэтому теперь я только добавляю INotifyChanged в свои ViewModels. Это упростило управление количеством "RaisePropertyChanged"... Мои представления никогда не ссылаются на модель напрямую.

Я работаю над своим первым проектом MVVM еще на моем третьем основном рефакторе: P

Ответ 4

Я согласен, что между View и ViewModel будет плотная связь. Но это может быть в некоторой степени смягчено с помощью IValueConverters, когда это возможно, для трансформаций.

Я пытаюсь сохранить свою бизнес-логику в своей модели ViewModel. Кроме того, я использую Viewmodel для изменения формы моей модели в соответствии с тем, что может ожидать просмотр.