Switch statements

11 minute read

Switch statements are a code smell. Complex conditionals can be hard to read. The same pattern of switch statements might be repeating in several locations.

Symptoms

There is a complex switch statement or a long sequence of if statements. The problem is not necessarily the switch itself but duplication. The code can be spread in different places. Adding a new condition means finding all the switch statements and changing them.

Solutions

Most of times when you see switch statements you should think of polymorphism. It is typical that the conditional uses some kind of type code.

If you need to isolate a switch, extract a method and possibly move the method.

If the switch is based on a type code, the simplest thing to do is to replace the type code with subclasses.

If you update the type code after the object is created, or already subclass this class for another reason, you have to replace the type code with state or strategy.

Once you have the inheritance structure in place, you can replace conditional with polymorphism.

If one of the conditional options is null, introduce a null object.

Replace type code with subclasses

Here we have a set of numbers that form a list of allowable values for a type code. The numbers are given understandable names via constants.

Introduce a null object

Having a method possibly return null means that you have to do null checks.

publicclassUser{privatebooleanauthenticated;publicbooleanisAuthenticated(){returnauthenticated;}}// Somewhere in the codepublicUsergetCurrentUser(){returnuser;}// ...Useruser=getCurrentUser();if(user!=null&amp;&amp;!user.isAuthenticated())redirectToUnauthorizedPage();

Instead of null we can return an object that has some kind of default behavior.

publicclassNullUserextendsUser{@OverridepublicbooleanisAuthenticated(){returnfalse;}}// Somewhere in the codepublicUsergetCurrentUser(){if(user!=null)returnuser;elsereturnnewNullUser();}// ...Useruser=getCurrentUser();if(!user.isAuthenticated())redirectToUnauthorizedPage();

Benefits

Replacing switch statements has several benefits:

Control flow code can be bulky. Moving code to subclasses follows the Single Responsibility Principle.

If you need to add a new type code, you can just add a new subclass without touching the existing code. This follows the Open/Closed Principle.

Instead of asking an object for its state and performing actions based on that it is easier to let the object decide what to do. This means following the Tell, Don’t Ask Principle.

In addition, removes duplicate code when you have several similar conditions.

Exceptions

In some cases replacing switch statements is not necessary:

If the switch operator performs very simple actions, there is no reason to change it.

A factory method or an abstract factory might use switch statements to create classes.

Summary

Switch statements are a code smell. Duplicated conditionals make changing the code hard.

Usually when you see switch statements operating on type codes you should think of replacing them with subclasses. If this is not possible, try replacing the type code with state or strategy. Null conditionals should be replaced with null objects.

Refactoring the switch statements make the code follow several object-oriented programming principles.

In very simple cases or when implementing factories, there is no reason to change the switch statements.