9

考虑到你有几个验证。只有当要检查的对象属于某种类型时,这些验证才会生效。为什么我要在 switch 语句上使用责任链?

责任链示例

public class Executor {

@Inject
private ValidatorFactory validatorFactory;

public void execute(Konfiguration konfig) {
    List<Statement> statements = konfig.getStatements();
    AbstractValidator validator = validatorFactory.create();
    for (Statement statement : statements) {
        if (validator.validate(statement.getType())) {
            crudService.execute(statement.getSql());
        }
    }
}

验证器工厂创建验证器链。一个验证器看起来像

public class AddPrimaryKeyValidator extends AbstractValidator {

@Override
public boolean validate(Statement statement) {
    if (SqlType.ADD_PK.getTyp().equals(statement.getType())) {
        return doesTableAndPrimaryKeyExist(statement.getTabName());
    }
    return successor.validate(statement);
}

带有 switch 语句的示例

public void execute(Konfiguration konfig) {
    List<Statement> statements = konfig.getStatements();
    for (Statement statement : statements) {
        switch (statement.getType()) {
        case "ADD_PK":
            if (doesTableAndPrimaryKeyExist(statement.getTabName())) {
                frepCrudService.execute(statement.getSql());
            }
            // more cases
        }
    }
}
4

2 回答 2

8

因为在责任链中,您不需要知道谁在调用者的前面做什么。决定何时在链中运行一段代码的逻辑归您所有,其余代码可以忽略它。这允许将特定逻辑封装在正确的位置。Servlet 过滤器就是一个很好的例子

于 2015-10-19T14:55:16.200 回答
0

使用责任链似乎是一个奇怪的理由。您基本上构建一个链只是为了创建一个动态的 if 语句列表,这可能不是动态的,因为我确信您对链初始化进行了硬编码,每个语句都有一个验证器。

我认为责任链不是正确的模式。您应该用多态性替换 if 语句。

例如,如果您有专门的Statement课程,您可以这样做statement.validate()Statement如果您不想,则不必验证自己,它只需知道在内部使用哪个验证器并将验证委托给它。

如果您没有专门的语句类,您可以立即向工厂询问正确的验证器,而不是构建整个链。

于 2015-10-20T05:15:44.523 回答