GWT MVP架构的优势 [英] GWT MVP architecture advantages

查看:81
本文介绍了GWT MVP架构的优势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习GWT,并且我已经在多个地方阅读过使用MVP架构最适合开发GWT应用程序的书籍。我也读过其易于执行的内容测试使用MVP ARCH.Can有人解释了为什么它很容易使用MVP架构进行测试。



另外我正在使用MVP进行一个项目,我发现它很单调乏味地让视图连接到数据库。我的意思是我必须更新我的演示者,服务,serviceAsync,servicImpl,Facades才能连接到数据库。



所以有人可以给我提供GWT的MVP精华吗?我会欣赏一些例子。

其中包含逻辑)和视图(一个愚蠢的UI控件包装)允许您:


  • 为可以运行的演示者编写单元测试需要相应的环境(桌面,浏览器,GWT小部件)

  • 不需要绑定到特定的小部件/ UI框架



后面的用例很少见,所以我们来关注MVP模型适用于自动化,程序化测试。通过一组开发者,这通常采用连续的构建/测试循环的形式,使用 Hudson (或类似的)一个无头的服务器,在每次测试运行时,打开一个Web浏览器,创建控件等是不现实的。

MVP + GWT的典型用法是视图实现演示者提供的接口,并且通常根据其他通用接口定义该接口。以下是一个非常简单的演示者,单击按钮时会增加数字标签 - 请注意,不是将 TextBox Button ,视图将返回一般的 HasText HasClickHandlers 实例:

  public class ButtonClickPresenter {
public interface View {
HasText currentValue();
HasClickHandlers incrementButton();
}

private final查看myView;
private int currentValue = 0;

public ButtonClickPresenter(查看myView){
this.myView = myView;
this.myView.currentValue()。setText(0);

this.bind(); //为了演示
}

public void bind(){
this.myView.incrementButton.addClickHandler(
@Override
new ClickHandler (){
void onClick(ClickEvent event){
currentValue ++;
myView.currentValue()。setText(
Integer.toString(currentValue));
}
});




$ p
$ b

真实视图返回UI小部件(通过创建UiBinder在这个例子中):

  public class ButtonClickView实现ButtonClickPresenter.View {
// ...跳过UiBinder初始化...

@UiField标签currentValueLabel;
@UiField Button incrementButton;

@Override
公共HasText currentValue(){
return currentValueLabel;
}

@Override
公共HasClickHandlers incrementButton(){
return incrementButton;
}

// ...等等...
}

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

  public class ButtonClickPresenterTest {
ButtonClickPresenter主讲人;
ClickHandler currentHandler;
字符串currentText;

@Before
public void setUp(){
presenter = new ButtonClickPresenter(
// dummy视图 - 仅将标签文本存储在字符串中,
//记录Presenter的点击处理程序
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(){
返回新的HasClickHandlers(){
@Override
公共HandlerRegistration addClickHandler(ClickHandler处理程序){
currentHandl er =处理程序;
}
};
}
});

$ b @Test
public void testIncrement(){
//初始值
assertEquals(0,currentText);

//点击按钮应该增加数字
currentHandler.onClick(null);
assertEquals(1,currentText);
}
}

至于你的下一段:你的意见不应该根本连接到数据库!演示者应通过Service / ServiceAsync(或抽象,如 gwt-dispatch gwt-platform ),然后调用视图上的方法来填充UI。



顺便说一句,最后两个链接(以及 gwt-presenter )是一个很好的开始,如果你正在寻找GWT MVP代码示例 - 结合

说了这么多,我同意 - GWT +的组合, MVP + Java可以很努力,并且非常详细(我很高兴现在不需要使用它)。然而,另一种选择则不那么有吸引力:一种无法测试的,不可维护的意大利面条球......


I am learning GWT and i have read at multiple places that using MVP architecture is best suitable to develop a GWT Application

I have also read that its easy to do testing using the MVP ARCH.Can somebody explain me why its easy to do testing using the MVP architecture.

Also i am working on a project using MVP and i find it very tedious to make the view connect to the data base.I mean i have to update my presenter,service,serviceAsync,servicImpl,Facades in order to make connection to database.

So can somebody provide me the essence of MVP for GWT?i would appreciate a couple of examples.

解决方案

Separation between the presenter (which contains logic) and view (a dumb wrapper around UI controls) allows you to:

  • write unit tests for the presenters that can run without needing the corresponding environment (desktop, browser, GWT widgets)
  • reuse front-end logic without being tied to a particular set of widgets/UI framework

The latter use case is rare, so let's focus on the MVP model's suitability for automated, programmatic testing. With a team of developers this often takes the form of a continuous build/test cycle using Hudson (or similar) on a headless server, where it's not practical to open a web browser, create controls, etc. every time a test is run.

Typical usage of MVP+GWT is that views implement an interface provided by the presenter, and often this interface is defined in terms of other generic interfaces. Here's a very simple presenter that increments a numeric label when a button is clicked - note that instead of exposing the TextBox and Button directly, the view returns generic HasText and HasClickHandlers instances:

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

The "real" view returns UI widgets (created via UiBinder in this example):

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 ...
}

whereas unit tests create a dummy implementation (or use Mockito, EasyMock, etc.) and thus don't require any UI components:

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

As for your next paragraph: your views shouldn't be connecting to the database at all! The presenter should request data via Service/ServiceAsync (or an abstraction such as gwt-dispatch or gwt-platform), then call methods on the view to populate the UI.

By the way, those last two links (along with gwt-presenter) are a good start if you're looking for GWT MVP code samples - combined with Google GIN they provide frameworks for tying all this stuff together.

Having said all that, I agree - the combination of GWT+MVP+Java can be hard work and extremely verbose (I'm glad I don't have to work with it much these days). The alternative, though, is even less attractive: an untestable, unmaintainable ball of spaghetti...

这篇关于GWT MVP架构的优势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆