jeudi 7 mars 2019

Java type specific behaviour with generics

The problem is as follows:

There are the entities Box, Boxvalue, Boxstrategy and then as example "IntegerBoxStrategy". The concept is quite simple, I'd like to put different kind of types in this box. Sometimes there will be an Integer inside this Box, sometimes a String. I want to be able to do specific conversion between these types (so type specific behaviour -> hence my strategy approach. Every type will require a specific strategy to convert) and these types can be specified with an ENUM.

So after googling a lot (though I'm quite sure this question might be marked as duplicate and say that I haven't googled enough ;) ) i'm trying this approach: https://www.javaspecialists.eu/archive/Issue123.html fyi: this question is really similar : Conditional behaviour based on concrete type for generic class though-> i want to be able to switch between my BoxValues, and convert "true" into "1";

The problem with the first link is that in every specific strategy implementation, I'm going to have a huge switch. (sample code later on)

My question is not something like "solve this for me please" but more like point me in the general direction. If a simple example could be given how this could be done when you don't have to update every specific strategy implementation when you support a new "boxvaluetype", I'd be really happy. If posssible, I'd like the cleanest design implementation or approach according to the GRASP principles.

 public interface typeStrategy {
    boolean canChangeToType(Object myvalue,ValueType type);
    boolean correctType(Object myvalue);
}

class BoolTypeStrategy implements typeStrategy{

    @Override
    public boolean canChangeToType(Object myvalue, ValueType type) {
        if (correctType(myvalue))
            throw new IllegalArgumentException("your initial value should be a boolean!");
        switch (type){
            case INT:
                return true;
            case STRING:
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean correctType(Object myvalue) {
        if (!(myvalue instanceof Boolean))
            return false;
        return true;
    }
}

In the example, this ValueType is my Enum.

public class BoxValue<T> {
    private T value;
    private typeStrategy mystrategy;


    public BoxValue(T value, typeStrategy strategy) {
        this.value = value;
        this.mystrategy = strategy;
    }

    public T getValue() {
        return value;
    }

    public boolean canChangeToType(ValueType type){
        return mystrategy.canChangeToType(value, type);
    }
}

As you can see, huge switches solve the problem.. So what design patterns, what suggestions are recommended to solve this problem? (fyi: I'd like to resolve this in Java 8, as i am aware that there are these strange "var" types in Java10+)

Aucun commentaire:

Enregistrer un commentaire