views:

917

answers:

9

I am curious to see any alternative(s) to the regular if statements such as

if(x)
     do a;
if(y)
     do b;
if(z)
    do c;

so as you see all if statements are seperate and no else condition. Please notice that X Y Z are totally seperate conditions so switch wouldn't fit.

+5  A: 

this is the most simple, readable yet effective solution. I would be surprised to see effective alternatives here.

EDIT

you can try to apply extract method several times:

doAIfX();
doBIfY();
doCifZ();

where methods are defined by:

void doAIfX() {
    if (!X) {
        return;
    }

    // do 'a'
}
dfa
No down vote but this doesn't feel right to me.
ChaosPandion
I do this in firmware for a device that can have many different options enabled or disabled. I'd rather have my main() call things like doFooIfEnabled() than clutter it up with lots of ifs and #ifdefs.
Jeanne Pindar
Like any pattern, there are times when it should be used, and times when it shouldn't.
bdonlan
A: 

it really depends on what x, y, z and a, b, c are. Sometimes if statements are more suitable. Sometimes polymorphism is more suitable.

Nat
+4  A: 

The alternatives to if-else in Java are the switch statement and the conditional ternary (?:) operator, neither of which do exactly what you're asking (handle just an if with no else). The code you posted is the best way to do it, in my opinion.

Bill the Lizard
A: 

Use polymorphism.

interface SomethingDoer {
    public void doSomething();
}

class ADoer implements SomethingDoer { ... }
class BDoer implements SomethingDoer { ... }
class CDoer implements SomethingDoer { ... }

public class Main {
     public static void main (String[] args) {
          SomethingDoer doer = new SomethingDoerFactory(args).getDoer();
          doer.doSomething();
     }
}

The if is not completely eliminated, but it is moved to SomethingDoerFactory. This solution is not applicable in all cases, but in some of them it is a very good alternative to multiple ifs.

Here is a nice talk about it:
http://misko.hevery.com/2008/12/08/clean-code-talks-inheritance-polymorphism-testing/

artemb
Any comments on why you downvote? Isn't it an alternative? Or isn't it good enough to be mentioned?
artemb
I'd only consider a polymorphic solution if my conditional was already based on **type**. I wouldn't create an entire class hierarchy just to replace `if(x) do a;`
Bill the Lizard
Andreas Petersson
Direct from Misko's slides: "sometimes an <code>if</code> is just an <code>if</code>". Unless you re-use these if statements in a lot of places, this is going to make things needlessly complex. Also: your solution is incomplete. What if both conditions x and y hold? You have missed AAndBDoer, AAndCDoer, BAndCDoer, AAndBAndCDoer; these are well-covered by the original code.
Zac Thompson
Obviously this depends on exactly what it means to "do a". Polymorphism might well be an excellent solution, but the example is simply too generic to have a single solution for all cases. AAndBDoer etc are typically solved by using Decorator/Composition patterns for a polymorphism-type solution.
Eek
+10  A: 

One "truely object oriented" answer would be to define an interface for "Rule" (with condition() and action() methods), create 3 implementations, stuff them into a collection, and then just iterate through them generically as in:

List<Rule> rules = .... ; // your 3 rules initialized here somehow
for(Rule r : rules) {
  if(r.condition()) {
    r.action();
  }
}

This makes a lot more sense if you have 300 rules/conditions rather than just 3.

Alex R
+4  A: 
Bill Bingham
A: 

You will need to have these if statements somewhere.

They can be refactored into other methods to keep the present method clean, as others have suggested. If you need to re-use this same set of if statements in a number of places, it might be possible use the Decorator Pattern.

Zac Thompson
A: 

Switch perhaps?

I can't think why you would want to replace it though.

Ben Shelock
A: 

It sounds like a perfect case for using closure. But for that you need groovy or something similar.

fastcodejava