One of the most consistent features I see in codebases that are in need of refactoring are developers doing terrible, terrible things with switch statements. They start out as small, manageable things but over time a series of expedient changes leaves you with a 1000 line long abomination full of duplicate code, hidden dependencies and unresolvable bugs.
One of the problems is that in most cases it seems so much more efficient to use a switch statement than the alternatives which generally need at least a couple of new classes. For a few cases this may be true but as the number of cases to be handled increases it becomes apparent that a switch statement is a form of
Technical Debt that must be paid. The limitations of a switch statement include:
- As the number of cases increases the switch statement grows beyond a size that can be easily considered.
- Where there are mutliple cases that behave in a similar fashion with their own customisations switch statements promote code duplication.
- It is not immediately clear what dependencies are exercised by each case. This can make validation very difficult.
- Switches work on a single criteria only. Supporting more complex conditionals can make the code almost impossible to follow.
- Large switch statements are difficult to adequately unit test.
Some of the problems can be mitigated by extracting the body the cases into methods, but this is still far from optimal. At this point it will likely be a similar effort to implement an alternate solution. Strategy or Command from the classic
Design Patterns suite many circumstances where switch statements are traditionally used.
Martin Fowler also discusses a number of solutions in
Refactoring: Improving the Design of Existing Code.