1

我有 3 个对象,一个称为 DTO BalanceDTO,它实现了一个接口RequestDTO和一个Balance实体。我创建了 DTO,因为我不能使用实体,JAXB 合规性(遗留代码)。

DTO 用于 Web 服务层,BalanceService以及我从 Web 服务集成到的 API 中的实体。在 Web 服务和 API 之间存在验证。RequestValidation它对每种类型的RequestDTOie都有子验证BalanceRequestValidation

验证组件接受 aRequestDTO作为参数,然后需要对特定组件进行验证。在输入点,验证组件不知道哪个对象已传递给它,即BalanceDTO,它只看到接口。

我想避免使用 instanceof,所以我想在 DTO 上使用访问者,以便它将自己委托给需要对其执行的验证。

但是验证需要更多/其他组件,而不仅仅是BalanceDTO输入参数,不同的验证需要不同的输入参数。

是否有另一种方法可以知道您正在使用哪个对象以及在不使用 instanceof 的情况下选择的验证?我可以遵循的另一个设计?

4

1 回答 1

1

您在这里走在正确的轨道上 - 访问者设计模式通常是避免向下转换的最佳方式。

我将建议将设计模式visitordelegation设计模式结合起来,但让我们来看看一些替代方案。

让对象通过RequestDTO接口自己进行验证是不可行的,因为您需要不同的组件,并且验证本质上并不是微不足道的。

使用instanceof和向下转换看起来有点混乱,如果您添加一个新的可验证类并忘记添加验证器,编译器不会抱怨 - 您将依赖于运行时错误...else { throw new IllegalArgumentException("Unknown RequestDTO subtype!"); }

设计模式是避免向下转换的visitor经典方法,而且如果您添加一个应该是可验证的新类并且忘记添加验证,它也会给您一个编译器错误。

您可以使用accept()andvisit()方法,或者您可以使用更接近您的域的方法命名,例如validate(),像这样:

public interface RequestDTO {
    boolean validate(RequestValidation validator);
}

public class BalanceDTO implements RequestDTO {
    // ...

    @Override
    public boolean validate(RequestValidation validator) {
        return validator.validate(this);
    }
}

public class RequestValidation {
    // components...

    public boolean validate(BalanceDTO balanceDTO) {
        return true;    // todo...
    }

    public boolean validate(AnotherDTO anotherDTO) {
        return true;    // todo...
    }
}

如果您想更进一步,您可以delegate对特定的验证组件进行验证,如下所示:

public class RequestValidation {
    BalanceRequestValidation balanceRequestValidation;
    AnotherRequestValidation anotherRequestValidation;

    public boolean validate(BalanceDTO balanceDTO) {
        return balanceRequestValidation.validate(balanceDTO, a, b, c);
    }

    public boolean validate(AnotherDTO anotherDTO) {
        return anotherRequestValidation.validate(anotherDTO, x, y, z);
    }
}

鉴于我已经正确理解了您的问题,visitor设计模式(可能与delegation设计模式相结合)确实是一种好方法。

于 2013-11-06T09:24:35.470 回答