如何在工厂模式下避免Java泛型警告

时间:2019-01-20 07:07:32

标签: java generics design-patterns rule-engine

我想通过使用Factory Design Pattern并添加某种规则链(如Rule Engine)来实现通用验证器,以在服务层中验证业务规则。我有可行的解决方案,我不确定这是否是最好的方法。

这是我的问题:我想确保编译时的类型安全,而不是在运行时检查类类型。因此,这将使开发人员可以安全地使用方法而不会遇到ClassCastException的机会。这是我要解决的最后警告,但到目前为止还无法解决,如果我的设计不清楚,我需要一些帮助并征求意见:

  

未经验证的原始类型成员对“ validate(T)”的调用   '... 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 :(得分:1)

首先,在AssignedSelectionValidatorFactory内,应在Validator上而不是在其具体实现上定义HAS-A关系。

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

创建工厂对象时,您需要传递T的有效类型,在您的情况下,该类型为AssignedSelectionValidatable

我希望这能解决您的问题。