我有3个对象,一个名为BalanceDTO
的DTO,它实现了一个接口RequestDTO
和一个Balance
实体。我创建了DTO,因为我无法使用的实体,JAXB合规性(遗留代码)。
DTO用于Web服务层BalanceService
,以及我从Web服务集成的API中的实体。在Web服务和API之间有验证。 RequestValidation
,其中包含RequestDTO
的每种类型的子验证,即BalanceRequestValidation
。
验证组件接受RequestDTO
作为参数,然后需要对特定组件进行验证。在输入时,验证组件不知道哪个对象已经传递给它,即BalanceDTO
,它只能看到界面。
我想避免使用instanceof,所以我想在DTO上使用访问者,以便将自己委托给需要在其上执行的验证。
但验证需要更多/其他组件,而不仅仅是BalanceDTO
作为输入参数,不同的验证需要不同的输入参数。
有没有其他方法可以知道您正在使用哪个对象以及在不使用instanceof的情况下选择验证?我可以遵循另一种设计吗?
答案 0 :(得分:1)
你在这里走得很好 - 访客设计模式通常是避免向下转化的最好方法。
我将建议visitor
和delegation
设计模式的组合,但我们将介绍一些替代方案。
让对象通过RequestDTO
接口自行进行验证是不可行的,因为你需要不同的组件,而且验证本质上并不简单。
使用instanceof
并且向下转换看起来有点混乱,如果你添加一个新的可验证类并忘记添加验证器,编译器不会抱怨 - 你将通过{{1来依赖运行时错误}}
...else { throw new IllegalArgumentException("Unknown RequestDTO subtype!"); }
设计模式是避免向下转换的经典方法,如果你添加一个应该可以验证的新类并忘记添加验证,它也会给你一个编译错误。
您可以使用visitor
和accept()
方法,也可以使用离您的域更近的方法命名,例如: visit()
,就像这样:
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
设计模式相结合)确实是一种很好的方法。