Как избежать предупреждений об универсальных элементах Java в шаблоне фабрики - PullRequest
0 голосов
/ 20 января 2019

Я хочу реализовать универсальный валидатор для проверки бизнес-правил на моем уровне обслуживания с использованием Factory Design Pattern и добавлением некоторого рода цепочки правил, таких как Rules Engine.У меня есть рабочее решение, которое я не уверен, если это лучший способ сделать.

Вот мой вопрос: я хочу обеспечить безопасность типов во время компиляции, а не иметь / проверять типы классов во время выполнения.Таким образом, разработчик сможет безопасно использовать метод, не имея возможности ClassCastException.Вот последнее предупреждение, которое я хочу решить, но пока не смог сделать это, мне нужна помощь и открою для совета. Если что-то не понятно в моем дизайне:

Непроверенный вызов 'validate(T) 'как элемент типа raw' ... Validator '

Строки Я получаю предупреждение:

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;
        }
    }
}

Вот интерфейс Validator

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: {}");
        }
    }
}

1 Ответ

0 голосов
/ 20 января 2019

Прежде всего, внутри AssignedSelectionValidatorFactory вы должны определить отношение HAS-A на Validator, а не на его конкретной реализации.

     public class AssignedSelectionValidatorFactory implements ValidatorFactory {
         private Validator<T> validator;
.......

Когда вы создаете объект фабрики, вам нужно будет передать допустимый тип для T, который в вашем случае будет AssignedSelectionValidatable

Надеюсь, это решит вашу проблему.

...