Работая с Google Web Toolkit, я написал приложение, основанное на концепции Model-View-Controller. Теперь у моего ClientController
класса есть два объекта типов ClientModel
и ClientView
, которые объявлены закрытыми и нестатическими. С объектом для асинхронных вызовов я написал несколько удаленных процедурных вызовов, которые работают, однако при подключении анонимного объекта типа AsyncCallback<T>
возникает проблема, так как я не могу получить доступ к двум объектам ClientModel
и ClientView
без записи некоторые неприятные final
переменные в моей функции, как вы можете видеть ниже:
package com.foo.bar;
/**
* Represents the main handler holding delegates and controlling the contents of
* the {@link ClientModel} and pushes notifications and message to both the
* {@link ClientModel} and the {@link ClientView}.
*/
public class ClientController {
/**
* Exposes asynchronous functions to call the server component via RPC.
*/
public static final MyServiceAsync mySvc = GWT.create(myService.class);
/**
* Represents the model associated with the {@link ClientController} object.
*/
private ClientModel theModel = null;
/**
* Represents the view associated with the {@link ClientController} object.
*/
private ClientView theView = null;
/**
* Creates a new {@link ClientController} object and instantiates both the
* {@link ClientModel} and the {@link ClientView}.
*/
public ClientController() {
this.theModel = new ClientModel();
this.theView = new ClientView(this.theModel);
}
/* some more code */
/**
* Tries to login the specified user and updates the {@link ClientView}
* object to either an error message or the main interface.
*
* @param user
* {@link User} object representing the user to login
*/
public void loginUser(final User user) {
///////////////////////////////////////////////
// THIS IS UGLY AND I DON'T KNOW HOW TO FIX THIS
///////////////////////////////////////////////
final ClientModel currentModel = this.theModel;
// Execute the login protocol
ClientController.mySvc.login(user, new AsyncCallback<Boolean>() {
/**
* The request was successfully executed. Returns a boolean value
* indicating whether the user was logged in.
*
* @param result
* true, if the user was logged in; otherwise, false.
*/
@Override
public void onSuccess(Boolean result) {
// The user was successfully logged in and we must both store
// him in the model and then update the view.
if (result) {
// TODO: Update the view to show the chat itself and save
// the current User to the ClientModel.
System.out.println("The User " + user.getUsername()
+ " is now logged in!");
// Anonymous object can not access the theModel and theView
// objects of ClientController directly ...
// drunk, fix later!
// UGLY FIX FOR NOW
currentModel.setCurrentUser(user);
} else {
// TODO: Unhide the error label of the login form and output
// some nice error message.
System.out.println("Login failed for User "
+ user.getUsername() + "!");
}
}
/**
* The request provoked an error.
*/
@Override
public void onFailure(Throwable up) {
try {
throw up; // Ha ha
} catch (Throwable e) {
// Who cares?
}
}
});
}
}
Сейчас я использую последний указатель на внутреннюю модель в loginUser
, который подсвечивается два раза. Может кто-нибудь объяснить мне, есть ли лучшее решение без перемещения theModel
и theView
на статические элементы? Раздражает необходимость писать такие «окончательные обертки» в каждой функции, к которой у вас есть доступ к любому из компонентов ...