В представлении есть один докладчик, но у докладчика может быть несколько представлений.

аюсь реализовать метод MVP впервые, используя WinForms.

Я пытаюсь понять функцию каждого слоя.

В моей программе у меня есть кнопка с графическим интерфейсом, которая при нажатии открывает окно openfiledialog.

Таким образом, используя MVP, графический интерфейс обрабатывает событие нажатия кнопки, а затем вызывает Presenter.openfile ();

Внутри Presenter.openfile () должен ли он затем делегировать открытие этого файла на уровне модели, или, если нет данных или логики для обработки, он должен просто воздействовать на запрос и открывать окно openfiledialog?

Обновить: Я решил предложить щедрость, поскольку я чувствую, что мне нужна дополнительная помощь в этом, и желательно с учетом моих конкретных моментов ниже, чтобы у меня был контекст.

Хорошо, после прочтения на MVP, я решил реализовать пассивный вид. По сути, у меня будет куча элементов управления в Winform, которые будут обрабатываться докладчиком, а затем задачи, делегированные моделям. Мои конкретные пункты ниже:

Когда winform загружается, она должна получить древовидную структуру. Правильно ли я считаю, что представление должно вызывать такой метод, как: Presenter.gettree (), это, в свою очередь, делегирует модели, которая получит данные для древовидного представления, создаст и настроит их, вернет их докладчик, который в свою очередь перейдет к представлению, которое затем просто назначит его, скажем, панели?

Будет ли это так же для любого элемента управления данными в Winform, поскольку у меня также есть сетевое представление данных?

Мое приложение имеет несколько классов моделей с одинаковой сборкой. Он также поддерживает архитектуру плагинов с плагинами, которые должны быть загружены при запуске. Будет ли представление просто вызывать метод презентатора, который в свою очередь вызовет метод, который загружает плагины и отображает информацию в представлении? Какой уровень будет контролировать ссылки на плагин. Будет ли представление содержать ссылки на них или докладчик?

Правильно ли я считаю, что представление должно обрабатывать все, что касается представления, от цвета узла дерева, до размера сетки данных и т. Д.?

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

 ak3nat0n01 июн. 2012 г., 21:42
Эта ссылкаlostechies.com/derekgreer/2008/11/23/... объясняет некоторые стили MVP. Это может оказаться полезным в дополнение к отличному ответу Иоганна.

Ответы на вопрос(3)

Решение Вопроса

Первыйвсе, с чем пользователь может взаимодействовать или просто может быть показан, являетсяПосмотреть, Законы, поведение и характеристики такого взгляда описываютсяинтерфейс, Этот интерфейс может быть реализован с использованием пользовательского интерфейса 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 (), это, в свою очередь, делегирует модели, которая получит данные для древовидного представления, создаст и настроит их, вернет их докладчик, который в свою очередь перейдет к представлению, которое затем просто назначит его, скажем, панели?

Я бы позвонилIConfigurationView.SetTreeData(...) изIConfigurationPresenter.ShowView()прямо перед звонкомIConfigurationView.Show()

2. Будет ли это так же для любого элемента управления данными в Winform, поскольку у меня также есть сетевое представление данных?

Да я бы позвонилIConfigurationView.SetTableData(...) для этого. Это до представления, чтобы отформатировать данные, предоставленные ему. Докладчик просто подчиняется договору представления о том, что ему нужны табличные данные.

3. Мое приложение имеет несколько классов моделей с одинаковой сборкой. Он также поддерживает архитектуру плагинов с плагинами, которые должны быть загружены при запуске. Будет ли представление просто вызывать метод презентатора, который в свою очередь вызовет метод, который загружает плагины и отображает информацию в представлении? Какой уровень будет контролировать ссылки на плагин. Будет ли представление содержать ссылки на них или докладчик?

Если плагины связаны с представлениями, то представления должны знать о них, но не о докладчике. Если они все о данных и модели, то представление не должно иметь ничего общего с ними.

4. Правильно ли я считаю, что представление должно обрабатывать все, что касается представления, от цвета узла дерева, до размера сетки данных и т. Д.?

Да. Думайте об этом как о докладчике, предоставляющем XML, который описывает данные и представление, которое берет данные и применяет к ним таблицу стилей CSS. Конкретно, докладчик может позвонитьIRoadMapView.SetRoadCondition(RoadCondition.Slippery) и представление тогда делает дорогу красным цветом.

А как насчет данных по нажатым узлам?

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

Если возможно, я бы передал все данные, необходимые для представления дерева в виде в одном кадре. Но если некоторые данные слишком велики, чтобы их можно было передать с самого начала, или если они динамичны по своей природе и нуждаются в «последнем снимке» из модели (через докладчика), то я бы добавил что-то вродеevent LoadNodeDetailsEventHandler LoadNodeDetails к интерфейсу представления, так что докладчик может подписаться на него, получить сведения об узле вLoadNodeDetailsEventArgs.Node (возможно, с помощью своего некоторого идентификатора) из модели, чтобы представление могло обновлять показанные сведения об узле при возврате делегата обработчика событий. Обратите внимание, что асинхронные шаблоны этого могут потребоваться, если выборка данных может быть слишком медленной для хорошего пользовательского опыта.

 ak3nat0n01 июн. 2012 г., 21:40
Я тоже склонен использовать инкапсулированный презентатор, как описано в этой ссылкеlostechies.com/derekgreer/2008/11/23/... в котором вид является единственным держателем презентатора.
 kasperhj21 июл. 2011 г., 21:33
Я не думаю, что вы обязательно должны отделить представление и докладчик. Я обычно отделяю модель и докладчика, когда докладчик слушает события модели и действует соответственно (обновляю представление). Наличие докладчика в представлении облегчает связь между представителем и представителем.
 Johann Gerell21 июл. 2011 г., 22:50
@lejon: Если, с другой стороны, представление отображает только фактическое событие, то сам докладчик (который знает, что он хочет делать, когда происходит событие представления) просто подписывается на него, чтобы делать правильные вещи. Это только «1 балл сложности», что в моей книге вдвое больше, чем «2 балла сложности». Вообще говоря, меньшее сцепление означает меньшую стоимость обслуживания в течение всего проекта.
 DavidRR11 авг. 2015 г., 17:26
@ ak3nat0n: Что касается трех стилей MVP, описанных в приведенной вами ссылке, я считаю, что этот ответ Иоганна может быть наиболее тесно связан с третьим стилем, который называетсяНаблюдение за стилем презентации: «Преимущество стиля Observing Presenter заключается в том, что он полностью отделяет знания Presenter от View, делая View менее восприимчивым к изменениям в Presenter».
 Johann Gerell21 июл. 2011 г., 22:50
@lejon: Вы говорите, чтоНаличие докладчика в представлении облегчает связь между представителем и докладчиком., но ясильно не согласны. Моя точка зрения такова: когда представление знает о докладчике, то для каждогопросмотреть событие вид должен решить, какойметод презентатора это правильный позвонить. Это "2 точки сложности", так как точка зрения не знает, какие именнопросмотреть событие что соответствует которомуметод презентатора, В договоре это не указано.

показывать окно openfiledialog, как вы предложили. Поскольку от модели не требуется никаких данных, докладчик может и должен обработать запрос.

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

 Darren Young25 янв. 2011 г., 15:36
Спасибо за ответ. Кроме того, у вас будет один ведущий для представления? И этот презентатор либо обрабатывает запрос, либо, если требуются данные, то он делегирует любое количество классов моделей, которые действуют на конкретные запросы? Это правильный путь? Еще раз спасибо.
 JochemKempe25 янв. 2011 г., 16:06
В представлении есть один докладчик, но у докладчика может быть несколько представлений.

логика на вид, должен реагировать на нажатие кнопки как @JochemKempeговорит, В практическом плане вызов обработчика события нажатия кнопкиpresenter.OpenFile(), Затем докладчик может определить, что должно быть сделано.

Если он решает, что пользователь должен выбрать файл, онперезванивает в поле зрения (через интерфейс представления), и пусть представление, которое содержит все технические аспекты пользовательского интерфейса, отображаетOpenFileDialog, Это очень важное различие в том, что докладчику нельзя разрешать выполнять операции, связанные с используемой технологией пользовательского интерфейса.

Затем выбранный файл будет возвращен докладчику, который продолжит свою логику. Это может включать любую модель или сервис, которые должны обрабатывать файл.

Основная причина использования шаблона MVP, imo, заключается в том, чтобы отделить технологию пользовательского интерфейса от логики представления. Таким образом, докладчик управляет всей логикой, в то время как представление хранит ее отдельно от логики пользовательского интерфейса. Это имеет очень приятный побочный эффект - сделать докладчика полностью тестируемым.

Обновить: поскольку ведущий является воплощением логики, найденной водин конкретный видотношения между представителем и представителем являются IMO отношения один-к-одному. И для всех практических целей один экземпляр представления (скажем, форма) взаимодействует с одним экземпляром презентатора, а один экземпляр презентатора взаимодействует только с одним экземпляром представления.

Тем не менее, в моей реализации MVP с WinForms докладчик всегда взаимодействует с представлением через интерфейс, представляющий пользовательские возможности представления. Нет ограничений на то, какое представление реализует этот интерфейс, поэтому разные «виджеты» могут реализовывать один и тот же интерфейс представления и повторно использовать класс презентатора.

 Peter Lillevold25 янв. 2011 г., 16:19
Правильно, я бы никогда не позволил докладчику открывать диалоговые окна напрямую, так как это сломало бы ваши тесты. Либо перенесите это в представление, либо, как я делал в некоторых сценариях, используйте отдельный класс FileOpenService для обработки фактического диалогового взаимодействия. Таким образом, вы можете подделать сервис открытия файлов во время тестов. Размещение такого кода в отдельном сервисе может дать вам хорошие побочные эффекты повторного использования :)
 Darren Young25 янв. 2011 г., 16:10
Благодарю. Таким образом, в методе Presenter.OpenFile () не должно быть кода, чтобы показать openfiledialog? Вместо этого он должен вернуться в представление, чтобы показать это окно?

Ваш ответ на вопрос