lundi 7 septembre 2020

Factory of generic type interfaces

I am looking for some help in designing the factory of concrete implementations of a generic interface. Java version 7, can not use 8+

Given such interface and abstract class:

public interface ValidationStrategy<T> {

    String getNativeQuery();
    ValidationStrategy<T> withValue(T value);
}

public abstract class AbstractValidationStrategy<T> implements ValidationStrategy<T> {

    protected T value;

    public void setValue(T value) {
        this.value = value;
    }
}

I want to have multiple implementations of such interface like:

public class DocumentValidationStrategy extends AbstractValidationStrategy<String> {
    @Override
    public String getNativeQuery() {
        // here goes customer native query
        return null;
    }

    @Override
    public ValidationStrategy<String> withValue(String value) {
        setValue(value);
        return this;
    }
}

The ValidationStrategy would be decided upon predefined enum (interface, has to be cross-platform unified) by the, ideally, a factory. The problems are generics and I can not really go around them with nor I haven't crossed any question that would address my problem

public class ValidationStrategyFactory {

    private static final Map<CustomerValueValidationEnum, Class<? extends ValidationStrategy<?>>> validationStrategiesMap = new HashMap<>();

    {
        validationStrategiesMap.put(CustomerValueValidationEnum.VALIDATE_DOCUMENT, DocumentValidationStrategy.class);

    }

    private static Class<? extends ValidationStrategy<?>> getInstance(CustomerValueValidationEnum validationEnum) {
        return validationStrategiesMap.get(validationEnum);
    }

    public static ValidationStrategy<?> createInstance(CustomerValueValidationEnum validationEnum)
            throws IllegalAccessException, InstantiationException {
        return getInstance(validationEnum).newInstance();
    }

}

This obviously leads to problems where I can not create the proper implemntation of the ValidationStrategy interface due to my bad usage of java generics where I try to:

public boolean isValueUnique(CustomerValueValidationEnum type, Object value) {

    try {
        ValidationStrategyFactory.createInstance(type).withValue(value);
    } catch (IllegalAccessException | InstantiationException e) {
        throw new UnsupportedOperationException();
    }

    return false;
}

which obviously does not work as I can not feed value the way I want (value can be everything, a String, Integer or a List). I know that I am trying to combine factory and strategy patterns and I tried my best to combine both of them, I guess it is a bad pattern but now I do not really know how else can I create easily extensible validation mechanism that would only require me to create a single class.





Aucun commentaire:

Enregistrer un commentaire