Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing if else statement with pattern

I have a if else statement which might grow in the near future.

    public void decide(String someCondition){          if(someCondition.equals("conditionOne")){             //             someMethod("someParameter");          }else if(someCondition.equals("conditionTwo")){             //            someMethod("anotherParameter");          }         .         .         else{              someMethod("elseParameter");          } } 

Since, this is already looking messy, I think it would be better if I can apply any design patterns here. I looked into Strategy pattern but I am not sure if that will reduce if else condition here. Any suggestions?

like image 708
cosmos Avatar asked Jan 20 '15 15:01

cosmos


People also ask

What is the replacement of if-else statement?

The Ternary Operator One of my favourite alternatives to if...else is the ternary operator. Here expressionIfTrue will be evaluated if condition evaluates to true ; otherwise expressionIfFalse will be evaluated. The beauty of ternary operators is they can be used on the right-hand side of an assignment.

How can we avoid multiple if-else using design patterns in Java?

Create an abstract base state class. Implement each state as a separate class inheriting from base state. Let the Booking ` class have a private or internal method that takes the state base class as a parameter.


2 Answers

This is a classic Replace Condition dispatcher with Command in the Refactoring to Patterns book.

enter image description here

Basically you make a Command object for each of the blocks of code in your old if/else group and then make a Map of those commands where the keys are your condition Strings

interface Handler{     void handle( myObject o); }    Map<String, Handler> commandMap = new HashMap<>();  //feel free to factor these out to their own class or  //if using Java 8 use the new Lambda syntax  commandMap.put("conditionOne", new Handler(){          void handle(MyObject o){                 //get desired parameters from MyObject and do stuff           }  });  ... 

Then instead of your if/else code it is instead:

 commandMap.get(someCondition).handle(this); 

Now if you need to later add new commands, you just add to the hash.

If you want to handle a default case, you can use the Null Object pattern to handle the case where a condition isn't in the Map.

 Handler defaultHandler = ...  if(commandMap.containsKey(someCondition)){     commandMap.get(someCondition).handle(this); }else{     defaultHandler.handle(this); } 
like image 173
dkatzel Avatar answered Sep 20 '22 15:09

dkatzel


The general recommendation by Martin Fowler is to Replace Conditional with Polymorphism.

In terms of design patterns this would often be the Strategy Pattern Replace Conditional Logic with Strategy.

If you have a small, finite set of conditions, I recommend to use an enum to implement the Strategy Pattern (provide an abstract method in the enum and override it for each constant).

public enum SomeCondition{    CONDITION_ONE{         public void someMethod(MyClass myClass){               //...        }    },     CONDITION_TWO{         public void someMethod(MyClass myClass){        }     }     public abstract void someMethod(MyClass myClass);  }  public class MyClass{ //...     public void decide(SomeCondition someCondition){         someCondition.someMethod(this);     }  } 

If it's really just a parameter you want to pick, then you could define the enum like this instead:

public enum SomeCondition{    CONDITION_ONE("parameterOne"),     CONDITION_TWO("parameterTwo");     private final String parameter;     private SomeCondition(String parameter){        this.parameter = parameter;    }     public String getParameter(){        return parameter;    }  }   public class MyClass{ //...     public void decide(SomeCondition someCondition){         someMethod(someCondition.getParameter());     }  } 
like image 45
Puce Avatar answered Sep 21 '22 15:09

Puce