Что такое MVP и MVC и в чем разница? - PullRequest
2010 голосов
/ 05 августа 2008

Если смотреть дальше RAD (перетаскивание и конфигурирование) способа создания пользовательских интерфейсов, который поощряется многими инструментами, вы, вероятно, столкнетесь с тремя шаблонами проектирования, называемыми Model-View-Controller , Model-View-Presenter и Model-View-ViewModel . Мой вопрос состоит из трех частей:

  1. Какие проблемы решают эти шаблоны?
  2. Чем они похожи?
  3. Чем они отличаются?

Ответы [ 22 ]

1910 голосов
/ 19 сентября 2008

Model-View-Presenter

В MVP Presenter содержит бизнес-логику пользовательского интерфейса для представления. Все вызовы из View делегируются непосредственно в Presenter. Презентатор также отделен непосредственно от представления и общается с ним через интерфейс. Это делается для того, чтобы разрешить насмешку над видом в модульном тесте. Одним из общих атрибутов MVP является то, что должно быть много двусторонней диспетчеризации. Например, когда кто-то нажимает кнопку «Сохранить», обработчик события делегирует метод «OnSave» докладчика. Как только сохранение завершено, Presenter затем перезвонит представлению через его интерфейс, чтобы представление могло отобразить, что сохранение завершено.

MVP имеет тенденцию быть очень естественным шаблоном для достижения отдельного представления в веб-формах. Причина в том, что представление всегда создается первым во время выполнения ASP.NET. Вы можете узнать больше об обоих вариантах .

Два основных варианта

Пассивное представление: Представление настолько глупо, насколько это возможно, и содержит почти нулевую логику. Ведущий - средний человек, который говорит с Видом и Моделью. Вид и Модель полностью защищены друг от друга. Модель может вызывать события, но докладчик подписывается на них для обновления представления. В пассивном просмотре нет прямой привязки данных, вместо этого вид предоставляет свойства сеттера, которые Presenter использует для установки данных. Все состояния управляются в Presenter, а не View.

  • Pro: максимальная тестируемость поверхности; чистое разделение вида и модели
  • Con: больше работы (например, всех свойств установщика), поскольку вы сами выполняете привязку всех данных.

Контролирующий контроллер: Presenter обрабатывает жесты пользователя. Представление привязывается к модели напрямую через привязку данных. В этом случае работа докладчика заключается в том, чтобы передать модель представлению, чтобы оно могло с ней связываться. Ведущий также будет содержать логику для таких жестов, как нажатие кнопки, навигация и т. Д.

  • Pro: благодаря использованию привязки данных количество кода уменьшается.
  • Con: есть менее тестируемая поверхность (из-за привязки данных), и в представлении меньше инкапсуляции, поскольку он напрямую взаимодействует с моделью.

Model-View-Controller

В MVC Контроллер отвечает за определение того, какое представление отображать в ответ на любое действие, в том числе при загрузке приложения. Это отличается от MVP, где действия направляются через представление к докладчику. В MVC каждое действие в представлении соотносится с вызовом контроллера и действием. В сети каждое действие включает в себя обращение к URL-адресу, на другой стороне которого есть контроллер, который отвечает. Как только этот Контроллер завершит свою обработку, он вернет правильный вид. Последовательность продолжается в течение всей жизни приложения:

    Action in the View
        -> Call to Controller
        -> Controller Logic
        -> Controller returns the View.

Еще одно большое отличие от MVC заключается в том, что представление напрямую не связывается с моделью. Представление просто визуализируется и полностью не имеет состояния. В реализациях MVC View обычно не имеет никакой логики в коде позади. Это противоречит MVP, где это абсолютно необходимо, потому что, если View не делегирует Presenter, он никогда не будет вызван.

Презентация модели

Еще один шаблон, на который стоит обратить внимание, - шаблон Presentation Model . В этом шаблоне нет предъявителя. Вместо этого представление напрямую связывается с моделью представления. Модель презентации - это модель, созданная специально для просмотра. Это означает, что эта Модель может предоставлять свойства, которые никогда не будут навязываться модели предметной области, поскольку это будет нарушением разделения интересов В этом случае модель представления связывается с моделью предметной области и может подписываться на события, поступающие из этой модели. Затем представление подписывается на события, поступающие из модели презентации, и обновляется соответствующим образом. Модель представления может предоставлять команды, которые представление использует для вызова действий. Преимущество этого подхода состоит в том, что вы можете по существу полностью удалить код, поскольку PM полностью инкапсулирует все поведение представления. Этот шаблон является очень сильным кандидатом для использования в приложениях WPF и также называется Model-View-ViewModel .

Существует статья MSDN о модели презентации и раздел в Руководстве по составным приложениям для WPF (прежняя призма) о Разделенных шаблонах презентации

413 голосов
/ 07 июля 2013

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

MVC

MVC

MVP

enter image description here

404 голосов
/ 05 августа 2008

Я писал об этом некоторое время назад, цитируя Отличный пост Тодда Снайдера о разнице между двумя :

Вот ключевые различия между шаблоны:

Шаблон MVP

  • Вид более слабо связан с моделью. Ведущий ответственность за привязку модели к вид.
  • Легче для модульного тестирования, потому что взаимодействие с представлением осуществляется интерфейс
  • Обычно вид на карту докладчика один к одному. Сложные представления могут иметь мульти докладчики.

Шаблон MVC

  • Контроллер основан на поведении и может быть распределен между просмотры
  • Может быть ответственным за определение того, какой вид отображать

Это лучшее объяснение в Интернете, которое я мог найти.

237 голосов
/ 13 сентября 2014

Вот иллюстрации, которые представляют коммуникационный поток

enter image description here

enter image description here

160 голосов
/ 26 августа 2008

MVP - это , а не , это обязательно сценарий, когда представление является ответственным (см. MVP Талигента, например).
Я сожалею, что люди все еще проповедуют это как шаблон («Представление во главе») в противоположность анти-шаблону, поскольку он противоречит «Это просто представление» (Pragmatic Programmer). «Это просто представление» гласит, что окончательное представление, отображаемое для пользователя, является второстепенной задачей приложения. Шаблон MVP от Microsoft значительно затрудняет повторное использование Views, а удобно освобождает дизайнера Microsoft от поощрения плохой практики.

Чтобы быть совершенно откровенным, я думаю, что основные проблемы MVC справедливы для любой реализации MVP, и различия почти полностью семантические. Пока вы следите за разделением интересов между представлением (которое отображает данные), контроллером (который инициализирует и контролирует взаимодействие с пользователем) и моделью (базовые данные и / или службы)), вы получаете преимущества MVC. , Если вы получаете преимущества, то кого действительно волнует, является ли ваш паттерн MVC, MVP или Supervising Controller? Единственный шаблон real остается в качестве MVC, остальные только отличаются друг от друга.

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

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

103 голосов
/ 07 августа 2008

MVP: представление отвечает.

Представление, в большинстве случаев, создает своего презентатора. Докладчик будет взаимодействовать с моделью и управлять видом через интерфейс. Представление иногда взаимодействует с докладчиком, как правило, через некоторый интерфейс. Это сводится к реализации; Вы хотите, чтобы представление вызывало методы для докладчика, или вы хотите, чтобы представление имело события, которые слушатель прослушивает? Это сводится к следующему: представление знает о ведущем. Представление делегатов докладчику.

MVC: контроллер отвечает.

Контроллер создается или доступен на основании какого-либо события / запроса. Затем контроллер создает соответствующий вид и взаимодействует с моделью для дальнейшей настройки вида. Это сводится к следующему: контроллер создает и управляет представлением; вид подчинен контроллеру. Представление не знает о контроллере.

71 голосов
/ 20 декабря 2015

enter image description here

MVC (контроллер представления модели)

Вход направлен в первую очередь на контроллер, а не на вид. Эти данные могут поступать от пользователя, взаимодействующего со страницей, но это также может быть просто от ввода определенного URL в браузер. В любом случае, это Контроллер, который взаимодействует с некоторыми функциональными возможностями. Между контроллером и представлением существует отношение многие-к-одному. Это связано с тем, что один контроллер может выбирать разные представления для визуализации в зависимости от выполняемой операции. Обратите внимание на одностороннюю стрелку от контроллера к представлению. Это связано с тем, что представление не имеет каких-либо знаний или ссылок на контроллер. Контроллер действительно передает Модель обратно, поэтому существует знание между Представлением и ожидаемой Моделью, передаваемой в него, но не Контроллер, обслуживающий ее.

MVP (ведущий модели)

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

Подробнее Справочник

43 голосов
/ 06 апреля 2018

Есть много ответов на этот вопрос, но я чувствовал, что нужен какой-то действительно простой ответ, четко сопоставляющий эти два вопроса. Вот обсуждение, которое я придумал, когда пользователь ищет название фильма в приложении MVP и MVC:

Пользователь: Нажмите, нажмите…

Просмотр : Кто это? [ MVP | MVC ]

Пользователь: Я только что нажал на кнопку поиска ...

Просмотр : Хорошо, подождите секунду…. [ MVP | MVC ]

( Просмотр вызова Presenter | Контроллер …) [ MVP | MVC ]

Вид : Привет Ведущий | Контроллер , пользователь только что нажал на кнопку поиска, что мне делать? [ MVP | MVC ]

Ведущий | Контроллер : Привет, Просмотр , есть ли поисковый запрос на этой странице? [ MVP | MVC ]

Просмотр : Да,… вот оно… «пианино» [ MVP | MVC ]

Ведущий : Спасибо Просмотр , ... пока что я ищу поисковый запрос по Модель , покажите ему / ей индикатор выполнения [ MVP | MVC ]

( Presenter | Контроллер вызывает Модель …) [ MVP | MVC ]

Ведущий | Контроллер : Привет Модель , У вас есть совпадения по этому поисковому запросу: «фортепиано» [ MVP | MVC ]

Модель : Привет Ведущий | Контроллер , позвольте мне проверить… [ MVP | MVC ]

( Модель делает запрос к базе данных фильмов…) [ MVP | MVC ]

(Через некоторое время ...)

-------------- Здесь MVP и MVC начинают расходиться ---------------

Модель : Я нашел для вас список, Ведущий , вот он в JSON “[{" name ":" Piano Teacher "," year ": 2001}, {"name": "Piano", "year": 1993}] »[ MVP ]

Модель : Доступен некоторый результат, Контроллер . Я создал переменную поля в моем экземпляре и заполнил ее результатом. Это имя "searchResultsList" [ MVC ]

( Presenter | Контроллер спасибо Модель и возвращается к View ) [ MVP | MVC ]

Ведущий : Спасибо за ожидание Просмотр , я нашел для вас список подходящих результатов и расположил их в презентабельном формате: ["Piano Teacher 2001", "Piano 1993" ]. Пожалуйста, покажите это пользователю в вертикальном списке. Также, пожалуйста, скройте индикатор выполнения сейчас [ MVP ]

Контроллер : Спасибо за ожидание Просмотр , я спросил Модель о вашем поисковом запросе. Он говорит, что нашел список совпадающих результатов и сохранил их в переменной с именем "searchResultsList" внутри своего экземпляра. Вы можете получить это оттуда. Также, пожалуйста, скройте индикатор выполнения сейчас [ MVC ]

Просмотр : Большое спасибо Ведущий [ MVP ]

Просмотр : Спасибо, "Контроллер" [ MVC ] (Теперь View задается вопросом: как представить пользователю результаты, полученные от Model ? Год выпуска фильма должен быть первым или последним ...? Должен ли он быть в вертикальном или горизонтальном списке? ...)

Если вам интересно, я пишу серию статей, касающихся архитектурных шаблонов приложений (MVC, MVP, MVVP, чистой архитектуры, ...), сопровождаемых репозиторием Github здесь . Несмотря на то, что образец написан для Android, основные принципы могут быть применены к любому носителю.

34 голосов
/ 05 августа 2008
  • MVP = Model-View-Presenter
  • MVC = Model-View-Controller

    1. Оба шаблона представления. Они разделяют зависимости между моделью (например, объектами домена), вашим экраном / веб-страницей (представлением) и поведением вашего пользовательского интерфейса (Presenter / Controller)
    2. Они довольно похожи по концепции, люди инициализируют Presenter / Controller по-разному в зависимости от вкуса.
    3. Отличная статья о различиях: здесь . Наиболее примечательным является то, что шаблон MVC имеет модель, обновляющую представление.
32 голосов
/ 08 августа 2008

Также стоит помнить, что существуют разные типы MVP. Фаулер разбил схему на две части - Пассивное представление и Контролирующий контроллер.

При использовании пассивного просмотра в вашем представлении обычно реализуется детализированный интерфейс со свойствами, более или менее сопоставленными непосредственно с лежащим в основе виджетом пользовательского интерфейса. Например, у вас может быть ICustomerView со свойствами, такими как Имя и Адрес.

Ваша реализация может выглядеть примерно так:

public class CustomerView : ICustomerView
{
    public string Name
    { 
        get { return txtName.Text; }
        set { txtName.Text = value; }
    }
}

Ваш класс Presenter поговорит с моделью и "сопоставит" ее с представлением. Этот подход называется «пассивным представлением». Преимущество состоит в том, что представление легко тестировать, и его легче перемещать между платформами пользовательского интерфейса (Web, Windows / XAML и т. Д.). Недостатком является то, что вы не можете использовать такие вещи, как привязка данных (которая является действительно мощной в таких средах, как WPF и Silverlight ).

Второй разновидностью MVP является Supervising Controller. В этом случае у вашего View может быть свойство Customer, которое опять-таки связано с виджетами пользовательского интерфейса. Вам не нужно думать о синхронизации и микро-управлении представлением, и Supervising Controller может вмешаться и помочь, когда это необходимо, например, с помощью сложной логики взаимодействия.

Третий «аромат» MVP (или кто-то мог бы назвать его отдельным шаблоном) - это модель представления (или иногда ее называют Model-View-ViewModel). По сравнению с MVP вы «объединяете» M и P в один класс. У вас есть объект customer, к которому привязаны ваши виджеты пользовательского интерфейса, но у вас также есть дополнительные специфичные для UI поля, такие как "IsButtonEnabled" или "IsReadOnly" и т. Д.

Я думаю, что лучший ресурс, который я нашел в архитектуре пользовательского интерфейса, - это серия постов в блоге, сделанных Джереми Миллером на Оглавление "Создайте свою собственную серию CAB" . Он рассмотрел все варианты MVP и показал код C # для их реализации.

Я также писал в блоге о модели Model-View-ViewModel в контексте Silverlight по адресу Повторное посещение YouCard: Реализация шаблона ViewModel .

...