Ways to eliminate switch in code
See the Switch Statements Smell:
Typically, similar switch statements are scattered throughout a program. If you add or remove a clause in one switch, you often have to find and repair the others too.
Both Refactoring and Refactoring to Patterns have approaches to resolve this.
If your (pseudo) code looks like:
class RequestHandler {
public void handleRequest(int action) {
switch(action) {
case LOGIN:
doLogin();
break;
case LOGOUT:
doLogout();
break;
case QUERY:
doQuery();
break;
}
}
}
This code violates the Open Closed Principle and is fragile to every new type of action code that comes along. To remedy this you could introduce a 'Command' object:
interface Command {
public void execute();
}
class LoginCommand implements Command {
public void execute() {
// do what doLogin() used to do
}
}
class RequestHandler {
private Map<Integer, Command> commandMap; // injected in, or obtained from a factory
public void handleRequest(int action) {
Command command = commandMap.get(action);
command.execute();
}
}
Hope this helps.
Switch-statements are not an antipattern per se, but if you're coding object oriented you should consider if the use of a switch is better solved with polymorphism instead of using a switch statement.
With polymorphism, this:
foreach (var animal in zoo) {
switch (typeof(animal)) {
case "dog":
echo animal.bark();
break;
case "cat":
echo animal.meow();
break;
}
}
becomes this:
foreach (var animal in zoo) {
echo animal.speak();
}
A switch is a pattern, whether implemented with a switch statement, if else chain, lookup table, oop polymorphism, pattern matching or something else.
Do you want to eliminate the use of the "switch statement" or the "switch pattern"? The first one can be eliminated, the second one, only if another pattern/algorithm can be used, and most of the time that is not possible or it's not a better approach to do so.
If you want to eliminate the switch statement from code, the first question to ask is where does it make sense to eliminate the switch statement and use some other technique. Unfortunately the answer to this question is domain specific.
And remember that compilers can do various optimizations to switch statements. So for example if you want to do message processing efficiently, a switch statement is pretty much the way to go. But on the other hand running business rules based on a switch statement is probably not the best way to go and the application should be rearchitected.
Here are some alternatives to switch statement :
- lookup table
- polymorphism
- pattern matching (especially used in functional programming, C++ templates)
Switch in itself isn't that bad, but if you have lots of "switch" or "if/else" on objects in your methods it may be a sign that your design is a bit "procedural" and that your objects are just value buckets. Move the logic to your objects, invoke a method on your objects and let them decide how to respond instead.