Правильно ли я реализую шаблон пользовательского интерфейса MVP/Presentation Model?

Я перерабатываю приложение Winforms и хотел бы использовать вариант шаблона Модель представления для пользовательского интерфейса. Может ли кто-нибудь сказать мне из следующих объяснений, правильно ли я это делаю?


Я решил настроить зависимости следующим образом:

   Model <---- Presentation Model <---- View

Это:

  • Модель ничего не осознает, кроме самой себя.

  • Модель представления имеет ссылку на модель (но не наоборот).

  • Представление имеет ссылку на модель представления (но не наоборот).

Я использую привязку данных Winforms для синхронизации представления и модели представления.

Теперь все это работает как шарм, за исключением случаев, когда мне нужно иметь дело, например. щелчок по кнопке «Закрыть» формы. Поскольку модель представления не имеет ссылки на представление, она не может подписаться ни на какие события, публикуемые представлением. Таким образом, я придумал следующий костыль:

Presentation Model                   View
+--+                                 +--+
|  |                                 |  |
|  |                                 | <--------X closeButton.Click event fires
|  |                                 |  |
|  |                         +--------X |
|  |   CloseRequested = true |       |  | 
|  |                         +--------> |
|  |                                 |  |
|  | CloseRequested   CloseRequested |  |
| <-----------------------------------< |
|  |                                 |  |
| X--------+                         |  |
|  |       | IsClosed = true         |  |
| <--------+                         |  |
|  |                                 |  |
|  | IsClosed              MustClose |  |
| >-----------------------------------> |
|  |                                 |  |
|  |                                 | X--------> view.Close()
|  |                                 |  |
+--+                                 +--+

Это:

  • Пользователь нажимает кнопку «Закрыть».

  • Событие кнопки Click фиксируется в представлении, которое реагирует установкой свойства CloseRequested.

  • Привязка данных передает это значение соответствующему свойству в модели представления.

  • Модель представления реагирует на это изменение, устанавливая свое свойство IsClosed.

  • Привязка данных передает это значение в представление MustClose.

  • Представление реагирует на это изменение, закрываясь.

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


person stakx - no longer contributing    schedule 08.08.2010    source источник


Ответы (3)


Недавно я преобразовывал приложение Windows Forms в архитектуру MVP, и похоже, что вы настроили свои зависимости так же, как это делал я. Однако у меня просто есть интерфейс IPresenter, который определяет методы, позволяющие представлению передавать запросы пользователей. Поскольку представление уже имеет зависимость от презентатора и ссылку на него, кажется разумным просто вызвать методы запроса непосредственно для него.

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

person Rich    schedule 09.08.2010

это только мое мнение.

Для работы с моделью представления требуется стопроцентная поддержка пользовательского интерфейса для привязки данных. Даже WPF не делает действие CLOSE как Bindable. Многое не будет работать гладко в модели презентации, такой как подтверждение MessageBox. даже его можно абстрагировать с помощью интерфейса Presenter, но все равно невкусно, а простота приносится в жертву.

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

person ktutnik    schedule 10.08.2010
comment
Я знаю, что привязка данных в Winforms не идеальна. (Например, он доступен только для элементов управления пользовательского интерфейса, а не для POCO. Кроме того, как следует из названия, он поддерживает только свойства, но не события.) Но действительно ли это основная проблема при реализации любого варианта шаблона MVP в Winforms? - person stakx - no longer contributing; 10.08.2010
comment
Да! потому что основным является Binding. В WPF это называется MVVM (Model — View — View Model), а в Adobe Flex — (модель представления). вы можете попробовать выполнить поиск подтверждение диалогового окна mvvm или модель презентации гибкой проверки, и вы увидите, что шаблон модели презентации приносит больше проблем, чем ясности. Я не говорю, что это плохой шаблон, но чтобы он работал на 100%, требуется 100% поддержка просмотра для привязки данных. Помните, что MVP и Модель презентации отличаются. Взгляните на nirajrules.wordpress.com/2009/07/18/mvc-vs-mvp-vs-mvvm - person ktutnik; 10.08.2010

Представление имеет ссылку на модель представления (но не наоборот).

Насколько я знаю, презентация должна иметь ссылку на более точное представление интерфейса IView, чтобы презентация не сочеталась с конкретным представлением. Затем в классе презентации вы можете вызвать методы просмотра и подписаться на просмотр событий через IView.

person Arseny    schedule 09.08.2010
comment
Есть много вариантов MVP, и я видел оба варианта. В описанном вами подходе презентатор будет зависеть как от модели, так и от IView. Кроме того, все представления требуются для реализации всех методов IView, даже тех, которые они не обрабатывают или не заботятся о них. При таком подходе презентатор зависит только от модели, а представление зависит только от презентатора. - person Rich; 09.08.2010
comment
нет, презентационная модель отличается от MPV. Thread Starter - это правильная модель представления, которая не должна ссылаться на пользовательский интерфейс, потому что ее должно быть легко проводить модульное тестирование. - person ktutnik; 10.08.2010
comment
@ktutnik, как я уже писал, Presenter получил ссылку на интерфейс IView, а не на элемент управления View, так что можно выполнить модульное тестирование класса Presenter. - person Arseny; 10.08.2010
comment
да, я вижу, и вы правы в контексте MVP!, но что касается Мартина Фаулера, модель презентации состоит только из View, PresentationModel и Model, модель презентации отличается от Presenter, модель презентации обновляет представление путем уведомления через привязку данных, но не обновляет напрямую Посмотреть. нет-нет иметь ссылку на пользовательский интерфейс, потому что это эволюция модели. ;) - person ktutnik; 10.08.2010