HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Method Of Retrieving Random Value Depending on Type

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
randommethodvaluetypedependingretrieving

Problem

I was wondering what would be the most appealing way of achieving this goal.

I have a blackbox. I give it a supported type and it returns a random value base off of the type.

For my supported types, I have an enum defined as follows:

public enum Types 
{
    INTEGER,
    DOUBLE,
    BIGINTEGER,
    BIGDECIMAL,
    STRING,
    BOOLEAN,
    CHAR
}


I thought the easiest way would be to create a static function which returns an Object based off of the Type

public static Object getRandomValue(Types type)
{
    switch(type)
    {
        case INTEGER:
            return randomInt();
        case DOUBLE:
            return randomDouble();
        case BIGINTEGER:
            return randomBigInt();
        case BIGDECIMAL:
            return randomBigDecimal();
        case STRING:
            return randomString();
        case BOOLEAN:
            return randomBool();
        case CHAR:
            return randomChar();
    }
}


The problem is that an additional cast would have to be made each time that I want to retrieve a random value based off of this method.

I've looked into the design patterns abstract factory and factory, and I can't decide if there's an advantage into implementing either of those. Or if there's a different design pattern that seems to be more appropriate.

Assume that all my random methods are defined.

Solution

Firstly if you are going to be passing objects of type Object around I guess you best be prepared to do a few casts here and there. You can achieve this using a simple interface and templates quite easily.

Interface:

public interface RandomGenerator  {
    T getRandom();
}


Implementation:

public class DoubleRandomGenerator implements RandomGenerator {

    @Override
    public Double getRandom() {
        //do what you do
        return 0d;
    }
}


Next, don't try to return every type of Object from the one Switch statement, it will always be ugly. In order to work out the next step maybe you could elaborate on what is happening outside the blackbox, e.g. if the calling code wants a Double you could add that into your enum:

public enum Types 
{
    INTEGER(new IntegerRandomGenerator()),
    DOUBLE(new DoubleRandomGenerator()),
    BIGINTEGER(...),
    BIGDECIMAL(...),
    STRING(...),
    BOOLEAN(...),
    CHAR(...);

    private RandomGenerator generator;

    private Types(RandomGenerator generator) {
         this.generator = generator;
    }

    public RandomGenerator getGenerator() {
         return generator;
    }
}


The main difference here is that you have deferred the creation of the random value to the callers end. The calling code will also be required to either use generics too:

RandomGenerator g = Types.DOUBLE.getGenerator();
Double d = g.getRandom();


Or generate warnings and cast the result:

RandomGenerator g = Types.DOUBLE.getGenerator();
Double d = (Double)g.getRandom();


Finally, you say you have read about the factory pattern, that is ultimately what you are playing with here.

Note. I think Enum naming should use the singular (Type) rather than the plural (Types), you are not selecting an Object of type Types as your Object (Types.DOUBLE) represents just one type.

Code Snippets

public interface RandomGenerator <T> {
    T getRandom();
}
public class DoubleRandomGenerator implements RandomGenerator<Double> {

    @Override
    public Double getRandom() {
        //do what you do
        return 0d;
    }
}
public enum Types 
{
    INTEGER(new IntegerRandomGenerator()),
    DOUBLE(new DoubleRandomGenerator()),
    BIGINTEGER(...),
    BIGDECIMAL(...),
    STRING(...),
    BOOLEAN(...),
    CHAR(...);

    private RandomGenerator generator;

    private Types(RandomGenerator generator) {
         this.generator = generator;
    }

    public RandomGenerator getGenerator() {
         return generator;
    }
}
RandomGenerator<Double> g = Types.DOUBLE.getGenerator();
Double d = g.getRandom();
RandomGenerator g = Types.DOUBLE.getGenerator();
Double d = (Double)g.getRandom();

Context

StackExchange Code Review Q#31146, answer score: 4

Revisions (0)

No revisions yet.