Создает ли презентатор в Model-View-Presenter представления?
Как создаются представления в MVP? Презентатор всегда создает их (в дополнение к View в случае подзаголовков)? Или это отдельный сторонний компонент или приложение или что-то, что их создает?
Также добавим, что я, вероятно, сделаю это на Dojo Toolkit/ExtJS (JavaScript, который есть).
Итак, у меня есть следующие строки кода:
var v = new MyApp.view.User();
var p = new MyApp.presenter.User();
где обе строки должны идти точно? Представляет ли экземпляр презентатора представление или наоборот? И что создает экземпляр первого экземпляра?
Ответы
Ответ 1
Это зависит...
Основная цель MVP заключается в том, чтобы отделить сложную логику решения от кода пользовательского интерфейса таким образом, чтобы и их стало легче понимать и поддерживать. Часто другая цель состоит в том, чтобы сделать логику решения в показателе презентатора.
Шаблон MVP был описан Фаулером в 2004 году, и он удалил его в 2006 году, разделив шаблон на Supervising Conroller (SC) и Пассивный просмотр (PV). В SC вид связан с моделью, но не в PV; в PV, представление только изменяется непосредственно на Presenter.
Как в SC, так и в PV, Presenter должен обновить View и на изменения, внесенные пользователем в представление, например, ввод текста или нажатие кнопки. Когда вы позволяете методам View View на презентаторе, тогда возникшая проблема возникает, потому что View нуждается в ссылке на Presenter и наоборот. Если вы это сделаете, вы просто можете принять решение, кто все это начнет. Возможные варианты:
- В представлении создается экземпляр презентатора. Когда View загружен, он передает себя в Presenter в функции инициализации в Presenter.
- Другой способ: Presenter создает View и переходит к представлению в функции инициализации в представлении.
- Вы вводите третий объект, который создает как View, так и Presenter, соединяет их вместе и инициализирует их оба.
Все параметры позволяют достичь "целей MVP" разделения проблем и повышения проверяемости логики принятия решений. Я не думаю, что любой из этих методов теоретически правильный или неправильный - вам просто нужно выбрать тот, который наиболее подходит для используемой вами технологии. И лучше всего быть последовательным в своем выборе во всем приложении.
Ответ 2
Это ваши варианты:
var cvp = new ContactViewPresenter(new ContactView());
ContactViewPresenter
наборы конструкторов this.view = viewParam
и устанавливает this.view.presenter = this
.
Он хранит код в Presenter, он может поменять местами просмотры, если это необходимо, и он может передать макет представления для тестирования.
var cv = new ContactView(new ContactViewPresenter());
ContactView
наборы конструкторов this.presenter = cvpParam
и this.presenter.view = this
.
Некоторая логика в представлении, но не много. При необходимости можете заменить презентатора.
ContactView cv = new ContactView();
ContactViewPresenter cvp = new ContactViewPresenter();
cv.presenter = cvp;
cvp.view = cv;
cv.init();
cvp.init();
Это намного больше кода.
ContactViewPresenter cvp = new ContactViewPresenter();
Конструктор создает наборы this.view = new ContactView()
и this.view.presenter = this
.
ContactView cv = new ContactView();
Наборы конструкторов this.presenter = new ContactViewPresenter()
и this.presenter.view = this
Последние два кажутся слишком связанными.
Хорошо, что код остается в Presenter и, кажется, позволяет упростить тестирование.
Два приятных в том, что вам не нужно слишком беспокоиться о докладчиках и больше беспокоиться о своих представлениях.
Ответ 3
Я не думаю, что Presenter должен создать экземпляр представления, который должен выполняться сущностью (а не в смысле, ориентированном на данные, я имею в виду общий объект) вне триады MVP. Например, структура инверсии управления (IoC) (если вы не слышали о IoC, проверьте статью Мартина Фаулера) или какой-либо модуль приложения отвечающий за конфигурацию пользователя.
Ответ 4
Если вы используете WebForms, то WebForm OnLoad или Init должен быть тем местом, где вы создаете Presenter - это затем передается ссылка на интерфейс, который реализует WebForm.
Итак, что-то вроде этого:
Presenter _presenter;
OnLoad(object sender, EventArgs e)
{
_presenter = new Presenter(this);
_presenter.Initialise();
}
И конструктор Presenter определяется таким образом:
public class Presenter
{
public Presenter(IView viewReference)
{
_viewReference = viewReference;
}
}
Ответ 5
У меня может быть неправильная терминология, но я думаю, вам нужно определить корневой состав вашего взаимодействия; что начинает взаимодействие?
В примере Webforms, который я дал, Webform создается конвейером Http, событие OnInit или OnLoad является первым пунктом в конвейере (в зависимости от того, какой контекст вам нужен), который вы можете "подключить" к процессу. Таким образом, вы создаете презентатор и даете ему конкретный экземпляр Webform в качестве интерфейса просмотра.
Я не знаю фреймворки Javascript, которые вы обсуждаете, но я предполагаю, что есть шаг инициализации/вызова - в ASP.NET MVC это когда задействован ActionInvoker, это основное в консольном приложении.