GWT MVP架构的优势

时间:2010-10-23 22:26:22

标签: gwt mvp

我正在学习GWT,我在多个地方读过使用MVP架构最适合开发GWT应用程序

我还读到使用MVP ARCH很容易进行测试。有人可以解释为什么使用MVP架构进行测试很容易。

此外我正在使用MVP进行项目,我发现将视图连接到数据库非常繁琐。我的意思是我必须更新我的演示者,服务,serviceAsync,servicImpl,Facades才能建立连接数据库中。

那么有人能为我提供GWT MVP的精髓吗?我会很感激几个例子。

2 个答案:

答案 0 :(得分:23)

演示者(包含逻辑)和视图(UI控件周围的哑包装)之间的分离允许您:

  • 为可以在不需要相应环境(桌面,浏览器,GWT小部件)的情况下运行的演示者编写单元测试
  • 重用前端逻辑,而不依赖于一组特定的小部件/ UI框架

后一种用例很少见,所以让我们关注MVP模型对自动化程序化测试的适用性。在开发人员团队中,这通常采用在无头服务器上使用Hudson(或类似)的连续构建/测试周期的形式,每次打开Web浏览器,创建控件等都是不切实际的。测试运行。

MVP + GWT的典型用法是视图实现由演示者提供的接口,并且该接口通常根据其他通用接口来定义。这是一个非常简单的演示者,在单击按钮时会递增数字标签 - 请注意,该视图不会直接显示TextBoxButton,而是返回通用HasTextHasClickHandlers实例:

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));
                }
            });
    }
}

“真实”视图返回UI小部件(在此示例中通过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 ...
}

而单元测试创​​建一个虚拟实现(或使用MockitoEasyMock等),因此不需要任何UI组件:

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-dispatchgwt-platform等抽象)请求数据,然后调用视图上的方法来填充UI。

顺便说一句,如果您正在寻找GWT MVP代码示例,那么最后两个链接(以及gwt-presenter)是一个良好的开端 - 与Google GIN结合它们提供了绑定所有这些东西的框架在一起。

说了这么多,我同意 - GWT + MVP + Java的结合可能很难,而且非常冗长(我很高兴这些天我不需要这么做)。然而,另一种选择更具吸引力:一个不可测试的,不可维护的意大利面球......

答案 1 :(得分:0)

您可能希望查看有关此处博客的示例gwt-platform应用程序 - > http://uptick.com.au/content/serendipity-working-gwt-platform-and-smartgwt

干杯 标记