образец посетителя против условных обозначений? - PullRequest
2 голосов
/ 09 августа 2009

Я не вижу этого в сценариях использования для шаблона посетителя (или, может быть, я не понимаю). Это также не иерархично.

Давайте использовать пример аутентификации. UserAuthenticator аутентифицирует учетные данные, предоставленные пользователем. Возвращает объект результата. Объект результата содержит результат аутентификации: аутентификация прошла успешно, не удалось, потому что имя пользователя не найдено, не удалось, потому что использовались недопустимые символы и т. Д. Код клиента может прибегнуть к условным вычислениям для обработки этого. В псевдокоде:

AuthResult = Userauthenticator.authenticate(Username, Password)
if AuthResult.isAuthenticated: do something
else if AuthResult.AuthFailedBecauseUsernameNotFound: do something else
else if etc...

Подойдет ли здесь шаблон посетителя? :

Authresult.acceptVisitor(AuthVisitor)

Authresult затем вызывает метод для AuthVisitor в зависимости от результата:

AuthVisitor.handleNotAuthenticatedBecauseUsernameNotFound

Ответы [ 2 ]

1 голос
/ 09 августа 2009

Посетитель - это ценный дизайн, когда ваши данные не изменяются так же быстро, как ваше поведение . Типичный пример с деревом разбора:

  • ваша иерархия классов (ваши данные) заморожена
  • ваше поведение меняется слишком сильно, вы не хотите прерывать занятия, добавляя еще один виртуальный метод

Я не думаю, что Посетитель является здесь ценным решением, поскольку каждый раз, когда вы добавляете подкласс AuthResult, вы нарушаете своего посетителя.

Посетитель о торговле инкапсуляцией с двойной отправкой .

Вы можете попробовать аналогичный подход:

interface Handler {

    void onUsernameNotFound();

    void onWrongPassword();

    void authOk();
}

interface Authenticator {
    void authenticate(String username, String password, Handler handler);  
}   

class SimpleAuthenticator implements Authetnciator {

    void authenticate(String username, String password, Handler handler) {
        if (username.equals("dfa")) {
            if (password.equals("I'm1337")) {
                handler.authOk();
            } else {
                handler.onWrongPassword();
            }
        } else {
            handler.onUsernameNotFound();
        }
    }
}

некоторые состояния обработчика:

class FatalHandler implements Handler {

    void onUsernameNotFound() {
        throw new AuthError("auth failed");
    }

    void onWrongPassword() {
        throw new AuthError("auth failed");
    }

    void authOk() {
        /* do something */
    }   
}

и

class DebugHandler implements Handler {

    void onUsernameNotFound() {
        System.out.println("wrong username");
    }

    void onWrongPassword() {
        System.out.println("wrong password");
    }

    void authOk() {
        System.out.println("ok");
    }   
}

теперь вы можете инкапсулировать обработку ошибок и операции в ваших Handler s, что намного меньше кода, чем Visitor, так как вам не нужна двойная отправка здесь.

1 голос
/ 09 августа 2009

Я бы не рекомендовал использовать шаблоны для намерений, для которых они не были созданы.

Намерения моделей посетителей :

  • Представляет операцию, выполняемую с элементами структуры объекта. Посетитель позволяет определить новую операцию, не изменяя классы элементов, с которыми он работает.
  • Классическая методика восстановления потерянной информации о типах.
  • Делайте правильные вещи, основываясь на типе двух объектов.
  • Двойная отправка

Это решение было бы полезно, если вы планировали использовать различные методы аутентификации, но если вы планируете использовать только один, вам все равно придется использовать условные выражения.

...