Преимущества архитектуры GWT MVP - PullRequest
7 голосов
/ 24 октября 2010

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

Я также прочитал, что его легко проводить с использованием MVP ARCH. Может кто-нибудь объяснитьПочему мне легко проводить тестирование с использованием архитектуры MVP.

Также я работаю над проектом, использующим MVP, и считаю очень утомительным подключение представления к базе данных. Я имею в виду, что мне нужно обновить свойPresenter, Service, ServiceAsync, servicImpl, Фасады для подключения к базе данных.

Так может ли кто-нибудь предоставить мне суть MVP для GWT? Я был бы признателен за пару примеров.

Ответы [ 2 ]

23 голосов
/ 24 октября 2010

Разделение между презентатором (который содержит логику) и видом (тупая обертка вокруг элементов управления пользовательского интерфейса) позволяет:

  • написать модульные тесты для докладчиков, которые могут работать без использования соответствующей среды (рабочий стол, браузер, виджеты 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 может быть тяжелой работой и чрезвычайно многословным (я рад, что мне не приходится много работать с этим в наши дни) , Альтернатива, тем не менее, еще менее привлекательна: непроверяемый, не поддерживаемый шар спагетти ...

0 голосов
/ 26 октября 2010

Возможно, вы захотите взглянуть на пример приложения на платформе gwt, о котором здесь написано-> http://uptick.com.au/content/serendipity-working-gwt-platform-and-smartgwt.

Cheers Mark

...