Разделение между презентатором (который содержит логику) и видом (тупая обертка вокруг элементов управления пользовательского интерфейса) позволяет:
- написать модульные тесты для докладчиков, которые могут работать без использования соответствующей среды (рабочий стол, браузер, виджеты GWT)
- повторное использование логики интерфейса без привязки к определенному набору виджетов / каркасу пользовательского интерфейса
Последний вариант использования встречается редко, поэтому давайте сосредоточимся на пригодности модели MVP для автоматизированного, программного тестирования. С командой разработчиков это часто принимает форму непрерывного цикла сборки / тестирования с использованием Hudson (или аналогичного) на сервере без монитора, где непрактично открывать веб-браузер, создавать элементы управления и т. Д. Каждый время выполнения теста.
Типичное использование MVP + GWT состоит в том, что представления реализуют интерфейс, предоставленный докладчиком, и часто этот интерфейс определяется в терминах других общих интерфейсов. Вот очень простой презентатор, который увеличивает числовую метку при нажатии кнопки - обратите внимание, что вместо непосредственного предоставления TextBox и Button представление возвращает универсальный HasText и HasClickHandlers экземпляров:
public class ButtonClickPresenter {
public interface View {
HasText currentValue();
HasClickHandlers incrementButton();
}
private final View myView;
private int currentValue = 0;
public ButtonClickPresenter(View myView) {
this.myView = myView;
this.myView.currentValue().setText("0");
this.bind(); // for the sake of demonstration
}
public void bind() {
this.myView.incrementButton.addClickHandler(
@Override
new ClickHandler() {
void onClick(ClickEvent event) {
currentValue ++;
myView.currentValue().setText(
Integer.toString(currentValue));
}
});
}
}
«Реальное» представление возвращает виджеты пользовательского интерфейса (созданные в этом примере с помощью UiBinder):
public class ButtonClickView implements ButtonClickPresenter.View {
// ... skipped UiBinder initialisation ...
@UiField Label currentValueLabel;
@UiField Button incrementButton;
@Override
public HasText currentValue() {
return currentValueLabel;
}
@Override
public HasClickHandlers incrementButton() {
return incrementButton;
}
// ... etc ...
}
, тогда как модульные тесты создают фиктивную реализацию (или используют Mockito , EasyMock и т. Д.) И, таким образом, не требуют никаких компонентов пользовательского интерфейса:
public class ButtonClickPresenterTest {
ButtonClickPresenter presenter;
ClickHandler currentHandler;
String currentText;
@Before
public void setUp() {
presenter = new ButtonClickPresenter(
// dummy view - just stores label text in a String and
// keeps track of the Presenter's click handler
new ButtonClickPresenter.View() {
@Override
public HasText currentValue() {
return new HasText() {
@Override public String getText() { return currentText; }
@Override public void setText(String text) { currentText = text; }
};
}
@Override
public HasClickHandlers incrementButton() {
return new HasClickHandlers() {
@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
currentHandler = handler;
}
};
}
});
}
@Test
public void testIncrement() {
// initial value
assertEquals("0", currentText);
// clicking the button should increment the number
currentHandler.onClick(null);
assertEquals("1", currentText);
}
}
Что касается вашего следующего абзаца: ваши представления вообще не должны подключаться к базе данных! Докладчик должен запросить данные через Service / ServiceAsync (или абстракцию, такую как gwt-dispatch или gwt-platform ), а затем вызвать методы в представлении для заполнения пользовательского интерфейса.
Кстати, эти две последние ссылки (вместе с gwt-Presenter ) - хорошее начало, если вы ищете примеры кода GWT MVP - в сочетании с Google GIN они обеспечить рамки для связывания всего этого вместе.
Сказав все это, я согласен - сочетание GWT + MVP + Java может быть тяжелой работой и чрезвычайно многословным (я рад, что мне не приходится много работать с этим в наши дни) , Альтернатива, тем не менее, еще менее привлекательна: непроверяемый, не поддерживаемый шар спагетти ...