Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing if else statements [duplicate]

I have a code which looks something like this:

if(num == 1) {
return new Alg1();
} else if (num == 2) {
return new Alg2();
}
...
else if (num == n) {
return new AlgN();
}

I have tried to use the Strategy pattern but it seems like it does not satisfy the task to reduce the if statements, can you please suggest me some other way to do it, thanks

like image 255
Tano Avatar asked Aug 14 '26 12:08

Tano


2 Answers

You can use reflection

try {
    return Class.forName("mypackage.Alg" + num).newInstance();
} catch (Exception e) { 
    // handle exception
}

You could chose to wrap with a RuntimeException or not wrap it if it was one you were expecting like

public static Algorythm loadAlgo(int n) throws IOException {
    try {
        return Class.forName("mypackage.Alg" + num).newInstance();

    } catch (Exception e) { 
        if (e instanceof IOException) 
            throw (IOException) e;
        throw new IOException("Unable to load Algo", e);
    }

You have to catch all exceptions not just checked ones with this newInstance() method as it doesn't wrap exceptions thrown in the constructor. You could use the longer

try {
    return Class.forName("mypackage.Alg" + num).getConstructor().newInstance();
} catch (Exception e) { 
    // handle exception
}

However, it doesn't make much difference in this case except exception thrown will be wrapped and you might have to unwrap them to see the original.

like image 67
Peter Lawrey Avatar answered Aug 16 '26 02:08

Peter Lawrey


Unless you're going to provide 4 billion Alg* classes, use an enum instead of an int:

enum Strategy {
  ALG_1 { @Override public Alg1 newInstance() { return new Alg1(); },
  ALG_2 { @Override public Alg2 newInstance() { return new Alg2(); },
  // ...
  ;

  public abstract AlgBase newInstance();
}

Then there is no need for any conditionals:

return strategy.newInstance();

where strategy is the instance of Strategy.

like image 24
Andy Turner Avatar answered Aug 16 '26 01:08

Andy Turner