2

ビジターパターンの使用シナリオではこれが見つからないようです(または、取得できない可能性があります)。また、階層的ではありません。

認証の例を使用してみましょう。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
4

2 に答える 2

1

意図されていない意図でパターンを使用することはお勧めしません。

訪問者パターンの意図は次のとおりです。

  • オブジェクト構造の要素に対して実行される操作を表します。Visitor を使用すると、操作対象の要素のクラスを変更せずに、新しい操作を定義できます。
  • 失われた型情報を回復するための古典的な手法。
  • 2 つのオブジェクトのタイプに基づいて正しいことを行います。
  • 二重発送

このソリューションは、さまざまな認証方法を実行する予定がある場合に役立ちますが、1 つだけを実行する予定がある場合は、とにかく条件を使用する必要があります。

于 2009-08-09T11:17:05.683 に答える
1

訪問者は、データが行動ほど速く変化しない場合に価値のある設計です。典型的な例は構文解析木です:

  • あなたのクラス階層(あなたのデータ)は凍結されています
  • あなたの行動はあまりにも多様で、別の仮想メソッドを追加してクラスを壊したくない

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();
        }
    }
}

いくつかの Handler ステートジー:

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 よりもはるかに少ないコードです。

于 2009-08-09T11:51:47.143 に答える