java - GWT 中的 MVP 模式 : How to initialize Model/View and handle server requests in the Presenter?

标签 java gwt mvp

这个问题不一定受 GWT 限制,但另一方面,这是我尝试正确使用它的结果。

我在 GWT 中使用 MVP 模式(建议),但我不确定如何处理模型和 View ,也不太确定如何创建对服务器。我特别想知道

  • 在哪里初始化MyView?演示者是否在构造函数中自行执行此操作,或者是否接收有效引用作为构造函数的参数?
  • MyModel相同。由于 MyModel 的实例可能在不同的演示者之间共享,我想它应该传递给演示者构造函数。
  • 如何在演示器中向服务器发出请求?我是否有一个额外的层来处理我的请求,或者是否建议在那里使用 MyServletAsync

我很难想出一个好的设计。请参阅下面的示例代码,该代码展示了我现在是如何做的:

public class MyPresenter implements MyView.MyPresenter

    private final MyServletAsync myService = MyServlet.Util.getInstance();

    private MyModel myModel;
    private MyView myView;

    public MyPresenter(MyView myView, MyModel myModel) {

        this.myView = myView;
        this.myModel = myModel;

        // Register click handler ..

        this.myView.getNextXyzButton.addClickHandler(
            new ClickHandler() {
                @Override
                public onClick(Event event) {
                    requestXyz(this.myModel.getXyz().getOffset() + 1);
                }
            });

        this.myView.getPrevisousXyzButton.addClickHandler(
            new ClickHandler() {
                @Override
                public onClick(Event event) {
                    requestXyz(this.myModel.getXyz().getOffset() - 1);
                }
            });

        // Initialize Xyz with offset 0
        requestXyz(0);
    }

    /*
     * Should I do this here in the presenter or should I 
     * create another layer that handles requests?
     */
    private void requestXyz(final int byOffset) {
        myService.getXyzFromServer(byOffset, new AsyncCallback<XyzDto>() {
            @Override
            public void onSuccess(XyzDto result) {
                updateModelWithResult(result);
            }
            @Override
            public void onFailure(Throwable caught) {
                displayError(caught);
            }
        });
    }

    private updateModelWithResult(Xyz result) {     
        this.myModel.setXyz(result);
        this.myView.displayXyz(result);
    }

    private displayError(Throwable caught) {
        // ..
    }

}

感谢您的建议。

最佳答案

MVP 模式很棒,它旨在隔离但调解完全不同的事物。然而,该模式并不决定它是如何实现的,这一切都取决于你自己,但当然要尊重某些方面。根据我的经验,我会说:

Where do I initialize MyView?

演示者最好接受某种 View 工厂(或一般的供应商,因为我们已经可以持有现有 View ,尤其是在 GWT 情况下),并让演示者决定何时实例化或接受 View 。我当前的项目使用一个小型自定义库,它定义了一个抽象演示者,这就是它的实现方式:

public abstract class AbstractPresenter<M extends IModel, V extends IView>
        implements IPresenter<M, V> {

    private final M model;
    private final V view;

    protected AbstractPresenter(final M model, final IViewFactory<V, ? super IPresenter<M, V>> viewFactory) {
        this.model = model;
        view = viewFactory.createView(this);
    }

...

}

传递 View 工厂的主要原因是将演示者注入(inject)到 View 中,因为 View 大多数应该引用它们各自的演示者(+我更喜欢有最终字段,所以这是一种同时拥有最终引用的方式:演示者到 View ,以及演示者 View )。

I guess it should be passes to the presenters constructor.

是的,它可以通过构造函数传递,如上例所示,但是有些人可能更喜欢 set-accessors,例如 setModelsetView

How do I make requests to the server in the presenter?

这就是模型的用途。演示者只是模型和 View 之间的中介,它基本上只负责两个方向的用户交互。考虑您的模型是访问应用程序的一种方式,因为模型不应被视为虚拟的“获取/设置字段”对象。模型是对服务层、网络通信(可以是服务背后的抽象)、数据存储或应用程序拥有的任何内容的抽象。因此,您的演示者只需通知模型获取或放置一些数据(分别从/到其他地方)。这也允许您编写完全抽象的层。如果您进行单元测试,那么您在测试演示者时就会遇到麻烦,因为 private final MyServletAsync myService = MyServlet.Util.getInstance(); 要求 Servlet 启动(这是一个坏主意,对吧) ?)。因此,如果 getXyzFromServer 成为模型的一部分(我想说,那么它可能会被命名为 getXyz 因为演示者并不真正关心 Xyz 在哪里> 是从)获取的,您可以轻松地模拟您的模型并仅测试演示者。

关于java - GWT 中的 MVP 模式 : How to initialize Model/View and handle server requests in the Presenter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32146099/

相关文章:

java - Java 中的字符串操作(确保字符串始终以“//”开头)

java - 针对错误服务器类路径的 Google Eclipse 插件警告

javascript - 扩展 CssLayout 的按钮无法可靠地触发单击事件

java - 如何为 GWT DecoratedTabPanel 实现复合 View /演示器?

winforms - MVP: View 或演示者应该了解模型吗?

java - 使用 libGDX 将 tmx 文件加载到 java 时出现异常

java - Jenkins 测试失败

java - 用于解决与云 API 的依赖关系的 Maven

java - GWT 中的标签上未触发单击事件

model-view-controller - WinJS:MVVM、MVP 或 MVC 更适合它吗?