Доступ к нестатическим объектам из анонимных объектов в Java - PullRequest
0 голосов
/ 02 сентября 2011

Работая с 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 на статические элементы? Раздражает необходимость писать такие «окончательные обертки» в каждой функции, к которой у вас есть доступ к любому из компонентов ...

Ответы [ 2 ]

3 голосов
/ 02 сентября 2011

Когда вы создаете экземпляр нестатического внутреннего класса или экземпляр анонимного класса, этот экземпляр имеет неявную привязку к экземпляру внешнего класса, которыйсоздал это.Вы можете получить доступ к членам внешнего класса из внутреннего класса, используя OuterClassName.this.member.

В вашем случае: ClientController.this.theModel

0 голосов
/ 02 сентября 2011

Попробуйте объявить своих участников финальными, как это:

...

private final ClientModel theModel;

private final ClientView theView;

public ClientController() {
    this.theModel = new ClientModel();
    this.theView = new ClientView(this.theModel);
}
...