簡體   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