Refactoring if/else logic

David picture David · May 26, 2010 · Viewed 21.7k times · Source

I have a java class with a thousand line method of if/else logic like this:

if (userType == "admin") {
     if (age > 12) {
          if (location == "USA") {
               // do stuff
          } else if (location == "Mexico") {
               // do something slightly different than the US case
          }
     } else if (age < 12 && age > 4) {
          if (location == "USA") {
               // do something slightly different than the age > 12 US case
          } else if (location == "Mexico") {
               // do something slightly different
          }
     }
 } else if (userType == "student") {
     if (age > 12) {
          if (location == "USA") {
               // do stuff
          } else if (location == "Mexico") {
               // do something slightly different than the US case
          }
     } else if (age < 12 && age > 4) {
          if (location == "USA") {
               // do something slightly different than the age > 12 US case
          } else if (location == "Mexico") {
               // do something slightly different
          }
     }

How should I refactor this into something more managable?

Answer

P&#233;ter T&#246;r&#246;k picture Péter Török · May 26, 2010

You should use Strategies, possibly implemented within an enum, e.g.:

enum UserType {
  ADMIN() {
    public void doStuff() {
      // do stuff the Admin way
    }
  },
  STUDENT {
    public void doStuff() {
      // do stuff the Student way
    }
  };

  public abstract void doStuff();
}

As the code structure within each outermost if branch in your code looks pretty much the same, in the next step of refactoring you might want to factor out that duplication using template methods. Alternatively, you might turn Location (and possibly Age) into a strategy as well.

Update: in Java4, you can implement a typesafe enum by hand, and use plain old subclassing to implement the different strategies.