I want to implement generic validator to validate business rules in my service layer with using Abstract Factory Design Pattern and adding some kinda rule chaining like Rules Engine. I have working solution which I'm not sure if it is the best way to do.
Here is my question: I want to ensure type safety in the compile time rather than having/checking class types in runtime. So it will make developer safe to use method without having chance of ClassCastException. Here is the last warning I want to solve but couldn't make it so far, I need some help and open for the advice If something is not clear in my design:
Unchecked call to 'validate(T)' as a member of raw type 'com.daimler.zasm.selection.control.validation.validator.Validator'
Lines I get the warning:
Validator validator = assignedSelectionValidatorFactory.createValidator(ValidationMode.SAVE);
validator.validate(new AssignedSelectionValidatable(assignSelectionRequestDto));
Here is my factory interface
public interface ValidatorFactory {
/**
* Creates factory which returns {@link Validator} based on the {@link ValidationMode}
*/
Validator createValidator(ValidationMode validationMode);
}
Here is my concrete implementation of the factory
@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;
}
}
}
Here is the Validator interface
public interface Validator<T extends Validatable> {
/**
* Validates each validation rules
*/
void validate(T objectsToValidate);
}
Here is the concrete implementation of Validator interface. This calls validation rules in its implementation
@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());
}
}
And here is the validation rule. Each validation rule is independent so they are reusable. Also I couldn't make them implement some ValidationRule -> apply(T genericInterface) interface since each ValidationRule may get different parameters. And I don't want to make it more complex by getting parameters from interface, but also open for any suggestions.
@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: {}");
}
}
}
Aucun commentaire:
Enregistrer un commentaire