GWT MVP UiBinder - передача аргументов докладчику - PullRequest
2 голосов
/ 29 сентября 2011

Я начал проект GWT, я решил попробовать UiBinder.Я испытываю трудности с укладкой шаблона MVP поверх UiBinder.

Когда я использовал GWT-pure-java: я использовал Джин, чтобы внедрить моего докладчика в соответствующее представление.Это было довольно просто, и если бы я хотел передать идентификатор в докладчика, то я бы просто передал идентификатор в конструктор докладчика.

Не так просто с UiBinder.Я почти уверен, что что-то упустил, потому что многие люди утверждают, что UiBinder и MVP - это совпадение, созданное на небесах ... поэтому я надеюсь получить несколько убедительных ответов на этот запрос; -)

То, что я видел в нескольких простых примерах GWT-UiBinder, заключается в том, что представление создается с помощью связывателя, а затем либо:

  1. Представление создает презентатор либо в его конструкторе, либо через @UIFactory method.
  2. Соответствующий презентатор передается в представление (через установщик, разумеется, после построения представления).

При первом подходе как передать идентификатор докладчику, если докладчик создается в представлении?Если бы вы сделали view.getPresenter().setId(42);, а затем докладчик пошел бы на сервер, чтобы получить некоторую информацию и попросить представление отобразить ее ... плохо пахнет.

При втором подходе можно получить не- интуитивно понятный объектный граф, в котором не ясно, кто является потребителем, а кто - производителем.Кроме того, в ситуациях, когда представление требует информации от докладчика (это требуется почти во всех сценариях использования), что можно сделать:

//some code would create the presenter pass it the id and then call view.setPresenter
class MyView {
    void setPresenter(MyPresenter p) {
    this.presenter = p;
    //OK now that i have my presenter how do I ask it to fetch data from the server.
    //do i turn around and do: presenter.setView(this); and then the presenter takes 
    //over and uses the view to display the data?
     }
 }

Это одинаково вонючее ... Извините за длинный пост, и спасибозаранее ...

Ответы [ 2 ]

6 голосов
/ 29 сентября 2011

Вы правы в том, что кажется немного нечистым иметь ссылку View как на своего Presenter и ссылку на Presenter на View.

То, как я это вижу, и как страницы разработчиков Googleна схеме MVP есть два вида MVP:

  1. Имейте представление, которое не знает о его презентаторе, и «оберните» его презентатором.Представление обеспечивает достаточный API для докладчика, чтобы получить / установить все данные, которые ему нужны.Кроме того, докладчик должен знать обо всех типах событий, которые может генерировать представление, чтобы реагировать на взаимодействие с пользователем.Это метод MPV part 1 .
  2. Презентатор еще раз знает о представлении, но на этот раз только при получении / установке емкости данных.Докладчик не заботится о событиях пользовательского интерфейса в представлении.Вместо этого докладчик предоставляет API для представления, чтобы вызывать / уведомлять его, когда события происходят в форме методов onSomethingHappened () в нашем докладчике.Это позволяет нам фиксировать все поведение / логику в самом презентаторе и вызывать его по мере необходимости, когда что-то происходит в представлении.Затем представление может обрабатывать события на очень низком уровне любым подходящим способом - будь то использование событий / виджетов GWT или необработанных событий DOM с элементами / HTML (лучшие практики производительности UiBinder / GWT).Это метод MVP часть 2 .

Я предпочитаю вариант 2, так как он позволяет докладчику просто сфокусироваться на необходимом поведении.Представление может иметь дело с виджетами / html / обработкой событий по мере необходимости и упрощать его до вызовов «onSomething ()» для ведущего.Эти реализации виджетов / событий могут быть простыми или сложными и оптимизированными событиями.Презентатор не подвержен влиянию (и не подвергается загрязнению) деталями, поскольку он просто получает уведомление.Я чувствую, что этот вариант - более четкое разделение представления и поведенияОбратите внимание, что это также 1: 1 реализация Observer Pattern , поэтому необходима взаимосвязь между View и Presenter.

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

Что касается аналогии с производителем / потребителем, я думаю, что выступающий является потребителем.Представление создает события пользовательского интерфейса (взаимодействие с пользователем), и докладчик отвечает, предоставляя необходимое поведение.Это должно быть единственной точкой соприкосновения между представлением и докладчиком - представление вызывает такие методы, как "onSomethingHappened ()", и докладчик выполняет свою работу.Представление никогда не сообщит докладчику "fetchData ()" или что-то в этом роде.

Я только недавно начал использовать UiBinder + MVP, так что это именно то, что я думаю.Надеюсь, это поможет!

0 голосов
/ 05 октября 2011

Прошло несколько дней с тех пор, как я начал эту тему и читал ответы. Я выбрал свой подход. И я думал, что просто упомяну это здесь.

Еще раз, спасибо за вдумчивые ответы ... они были полезны.

Как указал filip-fku, докладчики являются основной сущностью, поэтому я решил продолжать угрожать им как таковой во время управления жизненным циклом моих объектов mvp. Другими словами, представления не создают экземпляры докладчиков. Докладчики создаются другими докладчиками (в какой-то момент я делегирую Джину).

builder докладчика имеет доступ к соответствующему представлению и вводит докладчика (через конструктор) в представление.

Сами представления либо создаются builder, либо создаются UiBinder как часть более крупного представления. В последнем случае, когда UiBinder создает экземпляр представления, родительское представление имеет геттер. Вот пример этого случая:

/*pojo for the parent ui-binder*/
public class Form implements FormPresenter.View {
@UiField PromptView namePrompt;
@override
PromptPresenter.View getNamePromptDisplay() {
    return namePrompt;  //introduced into this pojo via @UiField
}
//bunch of view code
}//end of the class

Затем в FormPresenter я делаю:

private void buildNamePrompt() {
  new PromptPresenter(display.getNamePromptDisplay(), etc....);
}

По сути, я сохранил жизненный цикл mvp аналогично подходу чистой Java. Как только я получу немного прибыли, я сделаю рефакторинг с Джином.

Еще раз спасибо. Постскриптум Если вы не видели презентацию ввода / вывода, упомянутую выше, стоит проверить.

...