繁体   English   中英

GWT中的MVP模式:如何在Presenter中初始化Model / View和处理服务器请求?

[英]MVP Pattern in GWT: How to initialize Model/View and handle server requests in the Presenter?

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

我在GWT中使用MVP模式( 如推荐的那样 ),但是我不确定如何处理模型和视图,也不确定如何创建对服务器的请求。 我特别想知道

  • 在哪里初始化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模式很棒,它旨在隔离但可以调解完全不同的事物。 但是,该模式并不能决定如何实现它,而是完全由您自己决定,而是可以确保尊重某些方面。 根据我的经验,我会说:

在哪里初始化MyView?

演示者最好接受某种视图工厂(或一般来说是供应商,因为我们已经可以保存现有视图,尤其是在GWT情况下),然后让演示者决定何时实例化或接受视图。 我当前的项目使用一个小的自定义库,该库定义了一个抽象演示者,这是如何实现的:

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

...

}

通过视图工厂的主要原因是将演示者注入到视图中,因为视图大多应该引用其各自的演示者(+我更喜欢具有最终字段,因此这是同时具有两个最终引用的一种方式:演示者可以查看,并且查看演示者)。

我想应该将其传递给presenters构造函数。

是的,它可以通过上面的示例中的构造函数进行传递,但是有些人可能更喜欢setModelsetView类的集合访问setView

如何向演示者中的服务器发出请求?

这就是模型的目的。 演示者只是模型和视图之间的中介者,并且基本上只负责两个方向上的用户交互。 考虑模型是访问应用程序的一种方式,因为模型不应被视为虚拟的“获取/设置字段”对象。 模型是服务层,网络通信(可以是服务背后的抽象),数据存储或应用程序所具有的任何东西的抽象。 因此,您的演示者只需要通知模型以获取或放入一些数据(分别来自其他地方)。 这也使您可以编写完全抽象的图层。 如果进行单元测试,则由于private final MyServletAsync myService = MyServlet.Util.getInstance();您将难以测试演示者private final MyServletAsync myService = MyServlet.Util.getInstance(); 要求servlet正常运行(不好的主意,对吧?)。 所以,如果getXyzFromServer成为模型的一部分(我会说,那么它可能被命名为getXyz因为主持人并没有真正关心其中Xyz是牵强),你可以很容易地嘲笑你的模型,只是测试纯粹的主持人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM