Switch statements are commonly regarded as code smells, especially when the number of switch statements becomes very large. For this example I’m going to show you the traditional approach to refactor out a switch statement in C# and how you can further refine this approach using StructureMap though this would be possible using any IOC container.
Consider the following switch statement which I’ve kept fairly simple for the purpose of demonstration:
public void ProcessCommand(Command command)
{
switch (command)
{
case Command.Go:
Console.WriteLine("Go");
break;
case Command.Pause:
Console.WriteLine("Pause");
break;
case Command.Stop:
Console.WriteLine("Stop");
break;
default:
throw new Exception("Unhandled Command");
}
}
The Classic Approach To Refactoring Switch Statements
Normally when refactoring a switch statement we would perform the following steps:
1) Create an abstract/interface for a handler e.g.
public interface ICommandHandler
{
void Handle();
}
2) For each case statement create a concrete implementation of our abstract handler e.g.
public class GoHandler:ICommandHandler
{
public void Handle()
{
Console.WriteLine("Go");
}
public bool Handles(Command type)
{
return Command.Go == type;
}
}
3) Create a Dictionary of our handlers using our switch statement key for our dictionary key e.g.
public class RefactoredWithDictionary
{
private readonly Dictionary _commandHandlers;
public RefactoredWithDictionary()
{
_commandHandlers = new Dictionary
{
{Command.Go, new GoHandler()},
{Command.Pause, new PauseHandler()},
{Command.Stop, new StopHandler()}
};
}
public void DoSomethingWithTheSwitchStatement(Command command)
{
_commandHandlers[command].Handle();
}
}
Ok this is a big improvement from our previous switch statement it helps us get a bit closer to our S.O.L.I.D code Nirvana by adhering to our single responsibility principle and encapsulating our logic in specific handlers. However if we need to add a new handler we will need to modify the code by adding a new handler to the dictionary which violates our Open Closed Principle.