Я впервые пытаюсь реализовать метод MVP, используя WinForms.
Я пытаюсь понять функцию каждого слоя.
В моей программе у меня есть кнопка графического интерфейса, которая при нажатии открывает окно openfiledialog.
Таким образом, используя MVP, графический интерфейс обрабатывает событие нажатия кнопки, а затем вызывает presenter.openfile ();
Должен ли он в presenter.openfile () делегировать открытие этого файла на уровень модели, или, если нет данных или логики для обработки, следует ли просто действовать по запросу и открывать окно openfiledialog?
Обновить: я решил предложить вознаграждение, так как чувствую, что мне нужна дополнительная помощь в этом, и предпочтительно с учетом моих конкретных пунктов ниже, чтобы у меня был контекст.
Хорошо, прочитав о MVP, я решил реализовать пассивное представление. Фактически у меня будет набор элементов управления в Winform, которые будут обрабатываться Presenter, а затем задачи, делегированные модели (ам). Мои конкретные замечания приведены ниже:
Когда winform загружается, он должен получить древовидное представление. Правильно ли я полагаю, что представление должно поэтому вызывать такой метод, как: presenter.gettree (), это, в свою очередь, делегирует модель, которая получит данные для древовидного представления, создаст их и настроит, вернет их в ведущий, который, в свою очередь, перейдет к представлению, которое затем просто назначит его, скажем, панели?
Будет ли это то же самое для любого элемента управления данными в Winform, поскольку у меня также есть datagridview?
Мое приложение имеет несколько классов моделей с одной и той же сборкой. Он также поддерживает архитектуру плагинов с плагинами, которые необходимо загружать при запуске. Будет ли представление просто вызывать метод ведущего, который, в свою очередь, вызывает метод, загружающий плагины и отображающий информацию в представлении? Какой уровень затем будет управлять ссылками на подключаемые модули. Будет ли представление содержать ссылки на них или на докладчика?
Правильно ли я считаю, что представление должно обрабатывать все, что касается презентации, от цвета узла древовидного представления до размера сетки данных и т. Д.?
Я думаю, что это мои основные заботы, и если я пойму, какой поток должен быть для них, я думаю, что все будет в порядке.
Ответы:
Это мой скромный взгляд на MVP и ваши конкретные проблемы.
Во-первых , все, с чем пользователь может взаимодействовать или просто показывать, является представлением . Законы, поведение и характеристики такого вида описываются интерфейсом . Этот интерфейс может быть реализован с использованием пользовательского интерфейса WinForms, пользовательского интерфейса консоли, веб-интерфейса или даже без пользовательского интерфейса (обычно при тестировании докладчика) - конкретная реализация просто не имеет значения, если она подчиняется законам своего интерфейса представления. .
Во-вторых , представление всегда контролируется ведущим . Законы, поведение и характеристики такого ведущего также описываются интерфейсом . Этот интерфейс не заинтересован в конкретной реализации представления, пока он подчиняется законам своего интерфейса представления.
В третьих , поскольку презентатор управляет своим представлением, для минимизации зависимостей нет никакой пользы от того, чтобы представление вообще что-либо знало о своем презентаторе. Между докладчиком и представлением существует согласованный контракт, о чем свидетельствует интерфейс представления.
Последствия Третьего :
Для вашей проблемы приведенное выше может выглядеть в несколько упрощенном коде:
interface IConfigurationView { event EventHandler SelectConfigurationFile; void SetConfigurationFile(string fullPath); void Show(); } class ConfigurationView : IConfigurationView { Form form; Button selectConfigurationFileButton; Label fullPathLabel; public event EventHandler SelectConfigurationFile; public ConfigurationView() { // UI initialization. this.selectConfigurationFileButton.Click += delegate { var Handler = this.SelectConfigurationFile; if (Handler != null) { Handler(this, EventArgs.Empty); } }; } public void SetConfigurationFile(string fullPath) { this.fullPathLabel.Text = fullPath; } public void Show() { this.form.ShowDialog(); } } interface IConfigurationPresenter { void ShowView(); } class ConfigurationPresenter : IConfigurationPresenter { Configuration configuration = new Configuration(); IConfigurationView view; public ConfigurationPresenter(IConfigurationView view) { this.view = view; this.view.SelectConfigurationFile += delegate { // The ISelectFilePresenter and ISelectFileView behaviors // are implicit here, but in a WinForms case, a call to // OpenFileDialog wouldn't be too far fetched... var selectFilePresenter = Gimme.The<ISelectFilePresenter>(); selectFilePresenter.ShowView(); this.configuration.FullPath = selectFilePresenter.FullPath; this.view.SetConfigurationFile(this.configuration.FullPath); }; } public void ShowView() { this.view.SetConfigurationFile(this.configuration.FullPath); this.view.Show(); } }
В дополнение к вышесказанному у меня обычно есть базовый
IView
интерфейс, в котором я прячуShow()
и любое представление владельца или заголовок представления, от которого обычно выигрывают мои представления.На ваши вопросы:
1. Когда winform загружается, он должен получить древовидное представление. Правильно ли я полагаю, что представление должно поэтому вызывать такой метод, как: presenter.gettree (), это, в свою очередь, делегирует модель, которая получит данные для древовидного представления, создаст их и настроит, вернет их в ведущий, который, в свою очередь, перейдет к представлению, которое затем просто назначит его, скажем, панели?
2. Будет ли это то же самое для любого элемента управления данными в Winform, поскольку у меня также есть datagridview?
3. Мое приложение содержит несколько классов моделей с одной и той же сборкой. Он также поддерживает архитектуру плагинов с плагинами, которые необходимо загружать при запуске. Будет ли представление просто вызывать метод докладчика, который, в свою очередь, вызывает метод, который загружает плагины и отображает информацию в представлении? Какой уровень затем будет управлять ссылками на подключаемые модули. Будет ли представление содержать ссылки на них или на докладчика?
4. Правильно ли я считаю, что представление должно обрабатывать все, что касается представления, от цвета узла древовидного представления до размера сетки данных и т. Д.?
А как насчет данных для узлов, по которым щелкнули?
5. Если, когда я щелкаю по тринодам, должен ли я пройти через конкретный узел к ведущему, а затем, исходя из этого, ведущий определит, какие данные ему нужны, а затем запросит эти данные у модели, прежде чем представить их обратно в представление?
источник
Презентатор , который содержит всю логику в представлении, должен реагировать на нажатие кнопки, как говорит @JochemKempe . На практике это вызовы обработчика событий нажатия кнопки
presenter.OpenFile()
. Затем докладчик может определить, что следует делать.Если он решает, что пользователь должен выбрать файл, он обращается обратно в представление (через интерфейс представления) и позволяет представлению, которое содержит все технические характеристики пользовательского интерфейса, отображать файл
OpenFileDialog
. Это очень важное различие в том, что докладчику не должно быть разрешено выполнять операции, связанные с используемой технологией пользовательского интерфейса.Выбранный файл затем будет возвращен докладчику, который продолжит свою логику. Это может включать любую модель или службу, которая должна обрабатывать файл.
Основная причина использования шаблона MVP, imo, заключается в том, чтобы отделить технологию пользовательского интерфейса от логики представления. Таким образом, докладчик организует всю логику, в то время как представление хранит ее отдельно от логики пользовательского интерфейса. Это имеет очень приятный побочный эффект, делая докладчика полностью пригодным для модульного тестирования.
Обновление: поскольку ведущий является воплощением логики, найденной в одном конкретном представлении , отношения между представителем и презентатором являются отношениями IMO один-к-одному. И для всех практических целей один экземпляр представления (скажем, форма) взаимодействует с одним экземпляром презентатора, а один экземпляр презентатора взаимодействует только с одним экземпляром представления.
Тем не менее, в моей реализации MVP с WinForms докладчик всегда взаимодействует с представлением через интерфейс, представляющий возможности пользовательского интерфейса представления. Нет ограничений на то, какое представление реализует этот интерфейс, поэтому разные «виджеты» могут реализовывать один и тот же интерфейс представления и повторно использовать класс презентатора.
источник
Докладчик должен действовать в конце запроса, показывая окно openfiledialog, как вы предложили. Поскольку данные от модели не требуются, докладчик может и должен обработать запрос.
Предположим, вам нужны данные для создания некоторых сущностей в вашей модели. Вы можете передать поток на уровень доступа, где у вас есть метод для создания сущностей из потока, но я предлагаю вам обработать синтаксический анализ файла в вашем презентаторе и использовать конструктор или метод Create для каждой сущности в вашей модели.
источник