Составное руководство для WPF: MVVM против MVP - PullRequest
16 голосов
/ 08 мая 2009

Я в замешательстве. Может быть, вы можете помочь мне:)

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

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

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

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

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

Спасибо

Ariel

Ответы [ 4 ]

20 голосов
/ 04 сентября 2009

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

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

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

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

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

Независимо от того, насколько это НЕ СУХО, форсировать типы WCF или LINQ to SQL (или любой другой любимый ORM) для реализации INotifyProperyChanged хуже.

6 голосов
/ 08 мая 2009

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

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

6 голосов
/ 02 сентября 2009

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

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

Основное различие заключается в части Presenter vs 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.

5 голосов
/ 08 мая 2009

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

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

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

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

Удачи.

...