В прошлом я использовал MVP и MVC, и я предпочитаю MVP, так как, на мой взгляд, он намного лучше контролирует ход выполнения.
Я создал свою инфраструктуру (классы хранилища данных / репозитория) и без проблем использую их при жестком кодировании примеров данных, поэтому теперь я перехожу к графическому интерфейсу и готовлю свой MVP.
Раздел А
Я видел, как MVP использует представление в качестве точки входа, то есть в методе конструктора представлений он создает презентатор, который, в свою очередь, создает модель, связывая события по мере необходимости.
Я также видел презентатора как точку входа, где создаются представление, модель и презентатор, а затем этот презентатор получает объект представления и модели в своем конструкторе для связывания событий.
Как и в 2, но модель не передается ведущему. Вместо этого модель является статическим классом, где методы вызываются и ответы возвращаются напрямую.
Раздел Б
С точки зрения поддержания представления и модели в синхронизации я видел.
Всякий раз, когда значение в представлении изменяется, то есть
TextChanged
событие в .Net / C #. Это запускает объект,DataChangedEvent
который передается в модель, чтобы постоянно поддерживать его синхронизацию. И там, где модель изменяется, то есть фоновое событие, которое она слушает, тогда представление обновляется с помощью той же идеи подъемаDataChangedEvent
. Когда пользователь хочет зафиксировать изменения,SaveEvent
он срабатывает, передаваясь в модель для сохранения. В этом случае модель имитирует данные представления и обрабатывает действия.Аналогично # b1, однако представление не синхронизируется с моделью все время. Вместо этого, когда пользователь хочет зафиксировать изменения,
SaveEvent
он увольняется, и докладчик берет последние детали и передает их в модель. в этом случае модель не знает о данных представлений, пока не потребуется воздействовать на них, и в этом случае передаются все необходимые детали.
Раздел С
Отображение бизнес-объектов в представлении, т.е. объект (MyClass), не примитивные данные (int, double)
Представление имеет поля свойств для всех своих данных, которые будут отображаться как доменные / бизнес-объекты. Например,
view.Animals
предоставляетIEnumerable<IAnimal>
свойство, даже если представление обрабатывает их в узлах в TreeView. Тогда для выбранного животного это выставитSelectedAnimal
какIAnimal
собственность.Представление не знает об объектах домена, оно предоставляет свойство только для типов объектов, включенных в примитивы / рамки (.Net / Java). В этом случае презентатор передает объект адаптера объекту домена, затем адаптер преобразует данный бизнес-объект в элементы управления, видимые в представлении. В этом случае адаптер должен иметь доступ к фактическим элементам управления в представлении, а не только к любому представлению, поэтому он становится более тесно связанным.
Раздел D
Несколько представлений используются для создания одного элемента управления. т.е. у вас сложный вид с простой моделью, такой как сохранение объектов разных типов. У вас может быть система меню сбоку, при каждом щелчке на элементе отображаются соответствующие элементы управления.
Вы создаете одно огромное представление, которое содержит все отдельные элементы управления, которые предоставляются через интерфейс представлений.
У вас есть несколько просмотров. У вас есть один вид для меню и пустой панели. Это представление создает другие необходимые представления, но не отображает их (visible = false), это представление также реализует интерфейс для каждого представления, которое оно содержит (т. Е. Дочерние представления), поэтому оно может быть доступно одному докладчику. Пустая панель заполнена другими видами (
Controls.Add(myview)
) и ((myview.visible = true
). События, возникающие в этих «дочерних» представлениях, обрабатываются родительским представлением, которое, в свою очередь, передает событие докладчику, и наоборот, для передачи событий обратно дочерним элементам.Каждый вид, будь то основной родительский или меньший дочерний вид, каждый связан с их собственным презентатором и моделью. Вы можете буквально просто перетащить элемент управления представлением в существующую форму, и он будет иметь готовую функциональность, просто нужно подключиться к докладчику за кулисами.
Раздел Е
Если у всех есть интерфейс, теперь основанный на том, как MVP сделан в вышеприведенных примерах, повлияет на этот ответ, поскольку они могут быть несовместимыми.
У всего есть интерфейс, представление, презентатор и модель. Каждый из них, очевидно, имеет конкретную реализацию. Даже если у вас есть только один конкретный вид, модель и ведущий.
Вид и Модель имеют интерфейс. Это позволяет взглядам и моделям отличаться. Презентатор создает / получает вид и моделирует объекты, и он просто служит для передачи сообщений между ними.
Только вид имеет интерфейс. Модель имеет статические методы и не создается, поэтому нет необходимости в интерфейсе. Если вам нужна другая модель, докладчик вызывает другой набор статических методов класса. Будучи статичной, Модель не имеет ссылки на докладчика.
Личные мысли
Из всех различных вариантов, которые я представил (большинство я, вероятно, использовал в той или иной форме), которые, я уверен, есть и другие. Я предпочитаю A3, так как бизнес-логику можно использовать многократно за пределами MVP, B2 - для меньшего дублирования данных и меньшего количества инициируемых событий. C1, чтобы не добавлять в другой класс, конечно, он помещает небольшое количество логики, не поддающейся проверке, в представление (как визуализируется объект домена), но это может быть проверено кодом или просто просмотрено в приложении. Если бы логика была сложной, я бы согласился на класс адаптера, но не во всех случаях. Для раздела D я чувствую, что D1 создает представление, которое слишком велико по крайней мере для примера меню. Я использовал D2 и D3 раньше. Проблема с D2 заключается в том, что вам приходится писать много кода для маршрутизации событий от докладчика к правильному дочернему представлению, а он не совместим с перетаскиванием, каждому новому элементу управления требуется больше проводки для поддержки одного докладчика. D3 - мой предпочтительный выбор, но он добавляет еще больше классов в качестве докладчиков и моделей для работы с представлением, даже если представление оказывается очень простым или не нуждается в повторном использовании. Я думаю, что смесь D2 и D3 лучше всего зависит от обстоятельств. Что касается раздела E, я думаю, что все, что имеет интерфейс, может быть излишним, я уже делаю это для доменных / бизнес-объектов и часто не вижу в этом «никакого преимущества» в «дизайне», но это помогает при проверке объектов в тестах. Лично я бы видел E2 как классическое решение, хотя видел, как E3 использовался в 2 проектах, над которыми я работал ранее. Я думаю, что смесь D2 и D3 лучше всего зависит от обстоятельств. Что касается раздела E, я думаю, что все, что имеет интерфейс, может быть излишним, я уже делаю это для доменных / бизнес-объектов и часто не вижу в этом «никакого преимущества» в «дизайне», но это помогает при проверке объектов в тестах. Лично я бы видел E2 как классическое решение, хотя видел, как E3 использовался в 2 проектах, над которыми я работал ранее. Я думаю, что смесь D2 и D3 лучше всего зависит от обстоятельств. Что касается раздела E, я думаю, что все, что имеет интерфейс, может быть излишним, я уже делаю это для доменных / бизнес-объектов и часто не вижу в этом «никакого преимущества» в «дизайне», но это помогает при проверке объектов в тестах. Лично я бы видел E2 как классическое решение, хотя видел, как E3 использовался в 2 проектах, над которыми я работал ранее.
Вопрос
Я правильно внедряю MVP? Есть ли правильный способ сделать это?
Я читал работу Мартина Фаулера, в которой есть вариации, и я помню, когда я впервые начал заниматься MVC, я понял концепцию, но изначально не мог понять, где находится точка входа, у всего есть своя функция, но что контролирует и создает оригинал набор объектов MVC.