访客模式对条件?

时间:2009-08-09 11:03:27

标签: oop design-patterns visitor conditional

我似乎没有在访问者模式的使用场景中找到这个(或者我可能没有得到它)​​。它也没有等级。

让我们使用一个身份验证示例。 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 个答案:

答案 0 :(得分:1)

我不建议使用模式来表示它们不是为了制作它们。

the visitor patterns的意图是:

  • 表示要对对象结构的元素执行的操作。访问者允许您定义新操作,而无需更改其操作元素的类。
  • 恢复丢失类型信息的经典技巧。
  • 根据两个对象的类型做正确的事。
  • 双重发送

如果您计划进行各种身份验证方法,此解决方案将非常有用,但如果您只计划执行某种方法,则无论如何都必须使用条件。

答案 1 :(得分: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中封装错误处理和操作符,其代码比访问者少得多,因为您实际上并不需要双重调度。