Составное руководство для WPF: MVVM против MVP

Я смущен. Возможно ты можешь помочь мне :)

Я следовал указаниям CAG и нашел паттерн MVP очень естественным для меня. Предположим, у меня есть модель, готовая к использованию пользовательского интерфейса (например: реализует INotifyPropertyChanged), я использую презентатора для привязки этой модели к представлению (докладчик знает интерфейс представления), сохраняя минимальный размер моего кода позади, обрабатывая только привязки ( Model and Commands) свойства (или методы) или события для элементов управления, которые не имеют ICommand и в этом случае немедленно делегируются докладчику.

  1. Через некоторое время я обнаружил паттерн MVVM, и пока он ускользает от меня. Насколько я могу судить по своему подходу, я бы использовал MVVM только тогда, когда моя модель не готова к пользовательскому интерфейсу. Но было бы разумнее оставить докладчика и просто использовать новую Модель, я не понимаю, что я теряю при таком использовании. Я знаю, что чего-то не хватает, но что это? :).

  2. Также, когда ваше представление является общим и может обрабатывать многие виды моделей (например, в PropertyGrid). ViewModel рекомендуется использовать с DataTemplate, но в этом случае вы просто не можете создать шаблон для каждого объекта в вашей модели, его просто нужно исследовать во время выполнения, что вы порекомендуете?

  3. Наблюдая, как Джош Смит рассказывает о MVVM в скринкасте , У меня возникло ощущение, что повторное экспонирование модели в ViewModel нарушает DRY (не повторяйтесь), действительно ли это неизбежно? меня никого не удивляет его споры об этом по сравнению с пламенем Классы метаданных ADO.Net Dynamic Data появляются в настоящее время.

Надеюсь, это было достаточно ясно

Спасибо

Ариэль


person ArielBH    schedule 08.05.2009    source источник


Ответы (4)


Что касается №3, многие люди будут использовать аргумент «еще один уровень косвенности», говоря, что изменения в модели не повлияют на представление. Хотя это технически правильно, это не настоящая причина делать что-то подобное.

Если вы рассматриваете Модель как объекты, которые вы получаете, скажем, от уровня доступа к данным или службы (что обычно считается), вы начинаете понимать, зачем вам нужна ViewModel. ViewModel предназначен для расширения модели поведением, которое требуется View.

Например. Если вы хотите иметь возможность изменять свойство и получать уведомление об этом изменении посредством привязки, свойство должно вызвать некоторую форму NotifyPropertyChanged, чтобы представление могло реагировать. Это поведение, которого не будет у вашей типичной модели.

В другом примере предположим, что у вас есть коллекция, и вы хотите пометить каждый элемент в коллекции логическим значением, когда пользователь щелкает галочку рядом с этим элементом в представлении. Возможно, вам понадобится свойство IsSelected. Это поведение, которое Модель не должна обеспечивать.

Однако я вижу, откуда вы ... Сначала у меня определенно были проблемы с этим. Когда я в первый раз копирую и вставляю содержимое модели в свою модель просмотра, у меня перевернулся живот, но вам просто нужно смириться с тем фактом, что для того, чтобы ваше представление работало, ему понадобится этот дополнительный бит поведения, которого модель не должна Предоставлю.

Независимо от того, насколько это не DRY, принуждение ваших типов WCF или LINQ to SQL (или любого другого вашего любимого ORM) к реализации INotifyProperyChanged хуже.

person Anderson Imes    schedule 04.09.2009
comment
+1 Отличный ответ в целом, но последнее утверждение действительно возвращает его. - person jrista; 03.11.2009
comment
В нашей реализации MVVM у нас по-прежнему есть наша модель, написанная с учетом влияния доменно-ориентированного дизайна, а также некоторых вещей, извлеченных из фреймворков бизнес-объектов, таких как CSLA, которые уже реализуют INotifyProperyChanged. Пока что из-за нашего дизайна у нас намного меньше дублирования нашей модели в нашей ViewModel, и, как правило, нам нужно написать соответствующий класс ViewModel только тогда, когда нам нужно по-другому абстрагировать вещи для View, как упоминал Андерсон. - person jpierson; 30.01.2010

Помимо комментариев выше. Я хотел бы поделиться своим пониманием разницы.

Обычно в MVP у вас есть интерфейс просмотра, например. IView, чтобы абстрагироваться от реальных представлений и связывать данные с этими фактическими представлениями. Вместо этого в MVVM вы обычно используете DataContext фактического представления, например. пользовательский элемент управления XAML для привязки данных, аналогичный IView в MVP. Итак, допустим, неточно, привязка одинакова для обоих шаблонов.

Основное различие заключается в части Presenter и ViewModel. Модель представления сильно отличается от презентатора, который является мостом для обмена данными между пользовательским интерфейсом и моделью. На самом деле, как и означает его название, модель представления. Данные, представленные в ViewModel, в основном предназначены для пользовательского интерфейса. Итак, насколько я понимаю, в MVVM ViewModel - это абстракция представлений. Напротив, MVP в основном использует IView для абстрактных представлений. Так что обычно в MVVM меньше слоев, чем в MVP, и, следовательно, вы можете написать меньше кода для выполнения той же работы в MVVM:

MVVM: Модель - ViewModel (представляет фактические представления, то есть пользовательский интерфейс) - Фактические представления

MVP: Модель - Presenter (мост для обмена данными между моделью и пользовательским интерфейсом) - IView (представляет фактические представления, то есть пользовательский интерфейс) - Фактические представления

Преимущество MVVM над MVP в основном основано на следующих двух замечательных функциях в продуктах Microsoft:

  1. Командование в WPF. В будущем это может быть доступно в Silverlight, хотя уже есть некоторые реализации, которых нет в среде выполнения Silverlight.

  2. DataContext в WPF и Silverlight.

person Lixin    schedule 02.09.2009

Ad.3. Может показаться, что вы повторяете себя, выставляя модель в ViewModel, но на самом деле вы абстрагируете модель, так что View знает только об этой абстракции (View знает только о ViewModel).

Это связано с тем, что изменения в модели не должны нарушать представление. Также ваша Модель может быть реализована как множество различных сервисов, получающих данные из разных источников. В этом случае вам не хотелось бы, чтобы View знал обо всех из них, поэтому вы создаете другую абстракцию - ViewModel.

person Jarek Kardas    schedule 08.05.2009

Если докладчик знает интерфейс представления, вам нужно, чтобы все представления, используемые докладчиком, имели одинаковый интерфейс, или создать докладчика для каждого представления. С MVVM представление знает о viewModel, а viewModel знает о модели (но не наоборот). Это означает, что несколько представлений могут использовать виртуальную машину, а несколько виртуальных машин могут использовать модель.

Я не совсем понимаю, о чем вы спрашиваете во втором пункте. Виртуальная машина не является представлением (или не знает представления), и для меня DataTemplate определяет, как отображается объект. Я помещаю свои DataTemplates в ResourceDictionary, который определенно принадлежит View. Единственные "вещи" WPF на моем уровне виртуальной машины - это команды.

Мне нужно немного больше информации, чтобы ответить на ваш третий пункт. Возможно, он ответит сам, если вы немного углубитесь в MVVM.

Вот мой пост, который может вам помочь

Удачи.

person AndrewS    schedule 08.05.2009