Я пытаюсь получить хорошее представление о том, как реализовать хорошее разделение между пользовательским интерфейсом и моделью, но мне сложно понять, где именно разделить линии.
Я смотрел на Model-View-Presenter, но я не уверен, как именно реализовать его. Например, мой вид имеет несколько диалогов.
- Должен ли быть класс View с экземплярами каждого из диалогов? Тогда в таком случае, как диалоги должны взаимодействовать с докладчиком? то есть. если отдельное диалоговое окно должно запрашивать данные из модели через докладчик, как диалоговое окно должно получить ссылку на докладчик? Через ссылку на вид, данный ему во время строительства?
- Я думал, может быть, представление должно быть статическим классом? Тогда диалоги GetView и получить оттуда Presenter ...
- Я думал о настройке Presenter с правами на View и Model (в отличие от View с Presenter и Presenter с Model) и Presenter, регистрирующих обратные вызовы для событий в View, но из-за этого это выглядит много более связанный (или язык зависит, по крайней мере.)
Я пытаюсь:
- сделать это как можно отделенным
- в идеале сделать возможным связать Presenter / Model с представлениями других языков (я не делал тонны межъязыковых вещей, но я знаю, что это возможно, особенно, тем более
void(void)
я могу придерживаться, по крайней мере, приложения C # с Библиотека C ++ ... - сохранить код в чистоте и простоте
Итак ... какие-либо предложения, как взаимодействия должны быть обработаны?
design-patterns
ui
interfaces
попробуй поймать
источник
источник
Ответы:
Добро пожаловать на скользкий склон. К этому моменту вы поняли, что существует бесконечное разнообразие всех взаимодействий модели и вида. MVC, MVP (Taligent, Dolphin, Passive View), MVVM - это лишь некоторые из них.
Шаблон Model View Presenter, как и большинство архитектурных шаблонов, открыт для большого разнообразия и экспериментов. Единственное, что объединяет все вариации, это роль презентатора как посредника между представлением и моделью. Двумя наиболее распространенными являются пассивный просмотр и ведущий ведущий / контроллер - [ Фаулер ]. Пассивное представление рассматривает пользовательский интерфейс как очень поверхностный интерфейс между пользователем и докладчиком. В нем содержится очень мало логики, если она делегирует столько же ответственности докладчику. Супервайзер Ведущий / Контролерпытается использовать преимущества привязки данных, встроенной во многие инфраструктуры пользовательского интерфейса. Пользовательский интерфейс выполняет синхронизацию данных, но докладчик / контроллер вмешивается для более сложной логики. В любом случае модель, вид и презентатор образуют триаду
Есть много способов сделать это. Очень часто это можно увидеть, рассматривая каждый диалог / форму как отдельное представление. Часто между представлениями и докладчиками есть соотношение 1: 1. Это не сложное, быстрое правило. Довольно часто один докладчик обрабатывает несколько связанных представлений или наоборот. Все зависит от сложности представления и сложности бизнес-логики.
Что касается того, как представления и докладчики получают ссылку друг на друга, это иногда называют проводкой . У вас есть три варианта:
Представление содержит ссылку на докладчика
. Форма или диалоговое окно реализуют представление. Форма имеет обработчики событий, которые переходят к докладчику с помощью прямых вызовов функций:
Поскольку докладчик не имеет ссылки на представление, представление должно отправлять ему данные в качестве аргументов. Докладчик может связаться с представлением, используя функции событий / обратного вызова, которые представление должно прослушивать.
Presenter содержит ссылку на представление.
В сценарии представление предоставляет свойства для данных, которые оно отображает пользователю. Докладчик прослушивает события и манипулирует свойствами в представлении:
Оба содержат ссылку друг на друга, образуя круговую зависимость. С
этим сценарием на самом деле легче работать, чем с другими. Представление реагирует на события, вызывая методы в презентаторе. Докладчик считывает / изменяет данные из представления через открытые свойства.
Есть и другие проблемы, которые следует учитывать при использовании шаблонов MVP. Порядок создания, время жизни объекта, где происходит подключение, связь между триадами MVP, но этот ответ уже достаточно вырос.
источник
Как все говорили, существуют десятки мнений, и ни одно из них не является правильным или неправильным. Не вдаваясь во множество шаблонов и сосредотачиваясь только на MVP, вот несколько советов по реализации.
Держите их отдельно. Представление должно реализовывать интерфейс, который формирует связь между представлением и презентатором. Представление создает презентатора и внедряет себя в презентатора и предоставляет методы, которые оно предлагает для презентатора для взаимодействия с представлением. Представление отвечает за реализацию этих методов или свойств любым удобным для них способом. Как правило, у вас есть одно представление: один докладчик, но в некоторых случаях вы можете иметь несколько представлений: один докладчик (веб, wpf и т. Д.). Ключевым моментом здесь является то, что докладчик ничего не знает о реализации пользовательского интерфейса и взаимодействует только с представлением через интерфейс.
Вот пример. Сначала у нас есть класс представления с простым методом для отображения сообщения пользователю:
Теперь вот ведущий. Обратите внимание, что докладчик принимает IView в свой конструктор.
Теперь вот фактический пользовательский интерфейс. Это может быть окно, диалог, веб-страница и т. Д. Не имеет значения. Обратите внимание, что конструктор для представления создаст презентатора, внедрив себя в него.
Докладчик не заботится о том, как представление реализует метод, который он просто делает. Насколько известно докладчику, это может быть запись в файл журнала и даже не показ его пользователю.
В любом случае, ведущий выполняет некоторую работу с моделью на стороне сервера и в какой-то момент хочет проинформировать пользователя о том, что происходит. Так что теперь у нас есть метод где-то в презентере, который вызывает сообщение InformUser представлений.
Это где вы получаете свою развязку. Докладчик содержит только ссылку на реализацию IView, и ему все равно, как он реализован.
Это также плохая реализация, так как у вас есть ссылка на Presenter в представлении, а объекты задаются с помощью конструкторов. В более надежном решении вы, вероятно, захотите взглянуть на контейнеры инверсии управления (IoC), такие как Windsor, Ninject и т. Д., Которые позволят вам реализовать реализацию IView во время выполнения по запросу и, таким образом, сделать ее еще более отделенной.
источник
Я думаю, что важно помнить, что Controller / Presenter - это место, где действие действительно происходит. Сцепление в контроллере неизбежно из-за необходимости.
Суть Контроллера в том, что если вы вносите изменения в Представление, тогда Модель не должна изменяться, и наоборот (если Модель меняет Представление, это тоже не обязательно), потому что Контроллер - это то, что переводит Модель в представление и обратно. Но Контроллер изменится, когда изменятся либо Модель, либо Представление, потому что вы фактически должны преобразовать в Контроллере то, как Модель должна Просматривать, как вернуть изменения, сделанные в Представлении, обратно в Режим.
Лучший пример, который я могу привести, это то, что когда я пишу приложение MVC, я могу не только иметь данные в представлении GUI, но и написать подпрограмму, которая помещает данные, извлеченные из модели, в объект
string
для отображения в отладчике. (и, соответственно, в виде простого текстового файла). Если я могу взять данные модели и свободно перевести их в текст, не меняя представление или модель и только контроллер, то я на правильном пути.При этом вам нужно будет иметь ссылки между различными компонентами, чтобы все это работало. Контроллеру необходимо знать о представлении для передачи данных, а представление должно знать о контроллере, чтобы сообщить ему, когда было внесено изменение (например, когда пользователь нажимает «Сохранить» или «Новый ...»). Контроллер должен знать о модели, чтобы получить данные, но я бы сказал, что модель не должна знать ни о чем другом.
Предостережение: Я пришел из Mac, Objective-C, из Какао, который действительно подталкивает вас к парадигме MVC, хотите вы этого или нет.
источник
В общем, вы хотите, чтобы ваша модель инкапсулировала все взаимодействия с этой моделью. Например, все ваши действия CRUD (создание, чтение, обновление, удаление) являются частью модели. То же самое касается специальных расчетов. Для этого есть пара веских причин:
В вашем контроллере (приложение MVC) все, что вы делаете, - это собираете модели, которые вы должны использовать в своем представлении, и вызываете соответствующие функции в модели. Любые изменения в состоянии модели происходят в этом слое.
Ваш вид просто отображает модели, которые вы подготовили. По сути, представление только читает модель и соответствующим образом корректирует ее вывод.
Отображение общего принципа на реальные классы
Помните, что ваши диалоги являются представлениями. Если у вас уже есть класс диалога, нет причин создавать другой класс «View». Слой Presenter по существу связывает модель с элементами управления в представлении. Бизнес-логика и все важные данные хранятся в модели.
источник