【发布时间】:2019-01-20 07:07:32
【问题描述】:
我想实现通用验证器来验证我的服务层中的业务规则,方法是使用工厂设计模式并添加一些规则链,如规则引擎。我有可行的解决方案,我不确定这是否是最好的方法。
这是我的问题:我想在编译时确保类型安全,而不是在运行时拥有/检查类类型。因此,它将使开发人员可以安全地使用方法,而不会出现 ClassCastException。这是我想解决但到目前为止无法解决的最后一个警告,如果我的设计中有什么不清楚的地方,我需要一些帮助并接受建议:
对“validate(T)”的未经检查的调用作为原始类型的成员 '...验证器'
我收到警告的行:
Validator validator = assignedSelectionValidatorFactory.createValidator(ValidationMode.SAVE);
validator.validate(new AssignedSelectionValidatable(assignSelectionRequestDto));
这是我的工厂界面
public interface ValidatorFactory {
/**
* Creates factory which returns {@link Validator} based on the {@link ValidationMode}
*/
Validator createValidator(ValidationMode validationMode);
}
这是我对工厂的具体实现
@Component
public class AssignedSelectionValidatorFactory implements ValidatorFactory {
private AssignedSelectionSaveValidator assignedSelectionSaveValidator;
public AssignedSelectionValidatorFactory(AssignedSelectionSaveValidator assignedSelectionSaveValidator) {
this.assignedSelectionSaveValidator = assignedSelectionSaveValidator;
}
@Override
public Validator createValidator(ValidationMode validationMode) {
switch (validationMode) {
case SAVE:
return assignedSelectionSaveValidator;
default:
return null;
}
}
}
这里是验证器接口
public interface Validator<T extends Validatable> {
/**
* Validates each validation rules
*/
void validate(T objectsToValidate);
}
这里是Validator接口的具体实现。这在其实现中调用验证规则
@Component
public class AssignedSelectionSaveValidator implements Validator<AssignedSelectionValidatable> {
private AssignedSelectionUniqueRule assignedSelectionUniqueRule;
AssignedSelectionSaveValidator(AssignedSelectionUniqueRule assignedSelectionUniqueRule) {
this.assignedSelectionUniqueRule = assignedSelectionUniqueRule;
}
@Override
public void validate(AssignedSelectionValidatable assignedSelectionValidatable) {
assignedSelectionUniqueRule.apply(assignedSelectionValidatable.getAssignSelectionRequestDto());
}
}
这是验证规则。每个验证规则都是独立的,因此它们是可重用的。我也不能让他们实现一些 ValidationRule -> apply(T genericInterface) 接口,因为每个 ValidationRule 可能会得到不同的参数。而且我不想通过从界面获取参数使其变得更复杂,但也欢迎任何建议。
@Component
public class AssignedSelectionUniqueRule {
private AssignedSelectionRepository assignedSelectionRepository;
public AssignedSelectionUniqueRule(AssignedSelectionRepository assignedSelectionRepository) {
this.assignedSelectionRepository = assignedSelectionRepository;
}
public void apply(AssignSelectionRequestDto objectToValidate) {
Optional<AssignedSelection> foundAssignedSelection =
assignedSelectionRepository.getBy(objectToValidate.getSelectionDto().getId(),
objectToValidate.getCampaignUuid());
if (foundAssignedSelection.isPresent()) {
throw new BadRequestException(
"AssignedSelection is already exists with campaignUuid: {} and selectionUuid: {}");
}
}
}
【问题讨论】:
标签: java generics design-patterns rule-engine