ernitingoel
ernitingoel

Reputation: 661

Better way to handle n number of if-else if in java

I was wondering if there is any better way to handle n no. of if/else-if block in Java.

I have a situation where I need to print different values based on n no. of if/else-if/conditions blocks like

if(p==1 && q==r)
  System.out.println("Condition 1");
else if(r==p && q==9)
  System.out.println("Condition 2");
else if(z==1 && s==r)
  System.out.println("Condition 3");
else if(p==1 || x==r && y==7)
  System.out.println("Condition 4");
else if(q==z && y==r || p==4)
  System.out.println("Condition 5");
else if(x==z && r==5 || z==30)
  System.out.println("Condition 6");
else if(s==1 || q==x)
  System.out.println("Condition 7");
else if(r==14 || q==r++ || z==y)
  System.out.println("Condition 8");
else if(q==18 && s==r || p==90)
  System.out.println("Condition 9");
else if(y==19 || q==89)
  System.out.println("Condition 10");
...

Is there any other way to handle it instead of putting multiple if/else if statements so that if later on any new condition come, it will be easy to handle it.

Upvotes: 2

Views: 5622

Answers (3)

Mike Dunlavey
Mike Dunlavey

Reputation: 40699

Downvote bait

When you say "if any new condition come" do you mean you are willing to modify the code if a new condition comes, or must the code adapt without being modified? If the former, I think you've done it the best way. (Though, I would add an if (false){} at the top, so all the real cases look the same, making it easy to rearrange them.) If the latter, then a table-driven approach is needed. Performance is not an issue if every case has a print statement. If you do care about performance, then put the most common cases first.

If you care even more about performance, have a tree of if-statements, rather than a ladder. So, for example, have something like this, so you're not repeatedly asking the same sub-question:

if (p == 1){
    .. all the cases where p is 1
} else {
    .. all the other cases
}

There may be other OO-related ways to write this, but none of them will be faster or easier to modify than this.

Upvotes: 1

GhostCat
GhostCat

Reputation: 140613

The real answer here: don't do that.

In good OO design, you solve this problem in very different ways; for example by using polymorphism. You actually want to avoid having many different sources of information, to then make decisions on that.

In your case; I would be thinking towards FSMs and the state pattern for example.

What I mean is: your code is showing a certain "approach" towards solving a problem. And as long as you keep that approach as is, you are only talking about finding ways to express your solution in the "least ugly" way.

Instead, you should step back and look into approaches that can be expressed in "really beautiful" ways.

Thus: there is no "simple" direct answer to your question. You have to step back and have a close look at the requirements you want to fulfill; to then design a better, "more OO" solution to that.

The minimal thing here: you could start by declaring an enum like:

public enum Condition {
  A, B, C, ...

and then you would have some factory method that hides all those statements; like:

Condition currentCondition = determineCondition(p, q, r, z);
switch(currentCondition) {
  case A:

Meaning: you want to at least "centralize" that knowledge somewhere to avoid code duplication. But again; that is just like putting some new color on an old, rusty car. It helps for the moment, but doesn't really improve things.

Regarding your comments: yes, the switch is only marginally "better" than if elses. But as you said: you can't make too many chances, so at least you want to have exactly one piece of code that determines state.

But in the end: I think you are approaching this on a wrong level. You are probably dealing with some kind of complicated business logic; and you want to solve that on a low level like this. But nothing you do on such a level will lead to a robust, long-term maintainable solution. Probably the real solution is to step back and look into using some kind of workflow engine.

Upvotes: 1

Jeroen van Dijk-Jun
Jeroen van Dijk-Jun

Reputation: 1038

You can make a Condition (interface or superclass) which accepts all your variables:

public interface Condition {
    boolean isConditionMet(int p, int q, int r, int s, int x, int y, int z);
    void performAction();
}

For each single Condition you can override/implement a boolean method isConditionMet().

public class C1 implements Condition {
    public boolean isConditionMet(int p, int q, int r, int s, int x, int y, int z) {
        return p == 1 && q == r;
    }
    public void performAction() {
        System.out.println("Condition 1");
    }
}

Then you can put all conditions in a collection, and for each Condition you have you can ask:

if (condition.isConditionMet())
    condition.performAction();

Now each Condition object itself is responsible for when it should act, and what it should do then. A perfect separation of concerns.

Upvotes: 1

Related Questions