Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am currently refactoring my GWT client and try to apply the MVC pattern to all concerned classes. My problem is that I am not sure about two things here:

  • Where do I control which view gets displayed? For example if the user logs in and the start page should get loaded. Would the controller load that page or the model?
  • How would I best handle asynchronous callbacks and who (model or controller) is supposed to hold the async service?

I have this simple login example that is my actual code as it currently looks like:

LoginModel

// LoginModel appears kind of obsolete ..
public class LoginModel {

    private final LoginServiceAsync loginService = LoginService.Util.getInstance();

    public void onLoginClick(String userId, String password, AsyncCallback<UserDTO> asyncCallback) {        
        // Login on the server ..
        this.loginService.login(userId, password, asyncCallback);   
    }
}

LoginView

public class LoginView extends Composite {

    private static UILoginUiBinder uiBinder = GWT.create(UILoginUiBinder.class);

    @UiField Button btnLogin;
    @UiField TextBox txtPassword;
    @UiField TextBox txtUserID;

    interface UILoginUiBinder extends UiBinder<Widget, LoginView> {
    }

    public LoginView() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    public void addLoginButtonClickHandler(ClickHandler clickHandler) {
        this.btnLogin.addClickHandler(clickHandler);
    }

    public String getUserId() {
        return this.txtUserID.getText();
    }

    public String getPassword() {
        return this.txtPassword.getText();
    }

    public void displayLoginFailure() {     
        // TODO display login failure ..
    }
}

LoginController

public class LoginController {

    private final LoginModel loginModel;

    private final LoginView loginView;

    public LoginController(LoginModel loginModel, final LoginView loginView) {

        this.loginModel = loginModel;
        this.loginView = loginView;
        this.loginView.addLoginButtonClickHandler(new LoginButtonClickHandler());
    }

    private class LoginButtonClickHandler implements ClickHandler {
        @Override
        public void onClick(ClickEvent event) {

            loginModel.onLoginClick(loginView.getUserId(), loginView.getPassword(), new AsyncCallback<UserDTO>() {
                public void onFailure(Throwable caught) {
                    onLoginFailure(caught);
                }

                public void onSuccess(UserDTO userDto) {
                    onLoginSuccess(userDto);
                }
            });
        }
    }

    public void onLoginFailure(Throwable caught) {
        Throwable cause = caught.getCause();    
        if (cause instanceof LoginException) {
            GWT.log("Cause: " + cause.getMessage());
            cause.printStackTrace();
        }

        this.loginView.displayLoginFailure();
    }

    public void onLoginSuccess(UserDTO userDto) {
        // NOTE: UIStart is what is going to become StartView!
        UIStart home = new UIStart();
        RootPanel.get("mainUIContainer").clear();
        RootPanel.get("mainUIContainer").add(home);
    }
}

Is this a good implementation of the MVC pattern? Can I do better?

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.