degath
degath

Reputation: 1621

How to replace multi if/else statement if condition is a method with different params

I found answers where the condition was the same field e.g. if a==1 if a==2 etc. where I can easily change it to switch, but what in the case like below?

But what if the condition is a method (same method and difference is only in one parameter)

This is an example:

public float doSomething(Object object) throws invalidObjectException {
    float numberToReturn = 0f;

    if (isTypeValid(messages.getString("param1"), object.getType())) {
        //do something e.g.
        numberToReturn += Integer.parseInt(object.getTime()) * 1;
    } else if (isTypeValid(messages.getString("param2"), object.getType())) {
        //do something else e.g.
        numberToReturn += Float.parseFloat(object.getTime()) * 2;
    } else if (isTypeValid(messages.getString("param3"), object.getType())) {
        //do something else e.g.
        numberToReturn += Integer.parseInt(object.getTime()) * 3;

    } else {
        //do something else e.g.
        throw new invalidObjectException("Type " + object.getType() + " is invalid.");
    }
    return numberToReturn;
}

Like you can notice I have nearly same if conditions (difference is in a first param) and

Any ideas how to make it more readable for other programmers?

I think it is not really important, but this is how my isTpeValid looks like.

public boolean isTypeValid(String validTypes, String actualType) {
    String[] split = validTypes.split("\\s+");
    return Arrays.asList(split).contains(actualType) ? true : false;
}

messages.getString("param2") is a part of i18n (internatialization), where we have

ResourceBundle messages = ResourceBundle.getBundle("file_name", locale);

In a file_name_en I have example data with valid types for english:

param1=a b c
param2=d e
param3=f

In a file_name_de I have example data with valid types for german:

param1=g h
param2=i j k 
param3=l

So as example upper says:

if object.getType is valid with param1:
    //do something
if object.getType is valid with param2:
    //do something else etc.

Upvotes: 1

Views: 160

Answers (1)

Roman
Roman

Reputation: 5210

You can find a working example of the following code on repl.it

Code

You can replace the if-else by creating a lookup table that uses the type as a key and a function as the value.

Map<String, BiFunction<String, Float, Float>> typeFunctionLookup = new HashMap<>();
typeFunctionLookup.put("a", (time, x) -> x + Integer.parseInt(time) * 1);
typeFunctionLookup.put("b", (time, x) -> x + Float.parseFloat(time) * 2);
typeFunctionLookup.put("c", (time, x) -> x + Integer.parseInt(time) * 3);

After that we have to find a type within this lookup value. This could be done with:

public static Optional<Entry<String, BiFunction<String, Float, Float>>> findEntry(String type, Map<String, BiFunction<String, Float, Float>> types) {
    return types.entrySet().stream()
          .filter(x -> isTypeValid(x.getKey(), type))
          .findFirst();
}

findEntry returns an Optional. And if this option exists, we want to perform the function stored by the map. Otherwise we will just return the value without changing it by a function.

public static float handeType(Optional<Entry<String, BiFunction<String, Float, Float>>> type, String time, float value) {
    return type.isPresent() 
        ? type.get().getValue().apply(time, value)
        : value;
}

Now we can call handeType(findEntry(TYPE, typeFunctionLookup), OBJECT_TIME, OBJECT_TYPE)

Upvotes: 1

Related Questions