我目前正在重构我的GWT客户端并尝试将MVC模式应用于所有相关类。我的问题是我不确定这里有两件事:
我有这个简单的登录示例,它是我目前的实际代码:
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);
}
}
这是MVC模式的一个很好的实现吗?我可以做得更好吗?
答案 0 :(得分:1)
模型 - 视图 - 控制器(MVC)是用于实现用户界面的软件架构模式。它将给定的软件应用程序划分为三个相互关联的部分,以便将信息的内部表示与向用户呈现或接受信息的方式分开(来源:Wikipedia)
说,MVC有3个组件,
1)模型:理想情况下,它应该只包含getter和setter。这里不应该提到商业逻辑
2)查看:此部分仅包含视图。您不会在此处将视图链接到主html。它只是一个简单的视图,可以访问模型。
3)控制器:你所有的商业逻辑都应该放在这里。控制器可以访问视图和模型。
MVC w.r.t GWT应该是这样的。
第一个控制器被实例化。然后,控制器创建模型和视图的实例。
模型与视图链接,通常模型作为参数传递给视图。您可以像使用命令模式中的角度一样实现双重绑定,并根据需要更改侦听器或更新模型值(通常在保存或提交时)
现在来到你的异步部分。所有异步处理都应该在控制器上完成。在控制器中,异步调用成功后,应该更新模型,并且当模型与视图链接时,模型将更新视图。
我希望这可以回答你的问题并解释你的MVC范例。
答案 1 :(得分:1)
Ray Ryan在Google I / O 2009上发表了一篇演讲:Best Practices for Architecting GWT App
在GWT中你不使用MVC,你使用MVP(模型 - 视图 - 演示者),它更清晰地划分部分。您可以将MVP用于您的小部件和屏幕。 接下来使用EventBus来解耦组件。
最后你应该使用Acticities&amp;在您的应用程序内导航的地方。
看看这里: MVP Activities and Places。 这是一个很好的起源。
此外,您可以查看GWT-Platform GWTP或mvp4g,因为它们是GWT中mvp模式的不同实现。
正如Abhijith Nagaraja已经提到的那样:在演示者中进行异步调用。
修改:另请参阅Demystifying MVP and EventBus in GWT(摘自评论部分)。