Killing Switch Statements With A Registry: An Example And Screencast
Open To Change, Closed To Modification
The Open-Closed Principle (OCP) says that code should be opened to change in behavior, but closed to modification.
As I said in the talk, the best example of this is to look at hardware. Nearly every computing and mobile device out there has some sort of USB connection on it, these days. Plugging a USB device in to a laptop or desktop computer is a great example of how hardware is open to extension and change in behavior, without being required to change the existing hardware. You just plug the thumb drive, headset, camera, network adapter, or whatever it is in to the USB port and now your computer has additional behavior available. You’ve changed the system without changing the existing hardware.
Code works the same way. When we provide plugins, extensions, interface / protocol implementations or just pass objects as parameters in our code, we are providing a way to make that code extensible / extendable. We can change the behavior of the code by providing a different implementation of a given interface / protocol, without having to change the code that uses this interface / protocol. This is the essence of the open-closed principle (though there are a lot of other subtleties to watch when it comes to implementations).
OCP As Applied To Switch Statements
Switch statements are a simple way of providing flow control in your program. They let you decide which code is going to run, based on a given value. In the talk, I showed the following switch statement as an example:
There are several things I don’t like about switch statements, including the inability to change the behavior of the system without digging in to the switch statement itself. Every time you want to add a new thing to execute, you have to change the existing code. This clearly violates OCP by requiring changes to existing code instead of just allowing new behaviors to be added without changing existing code.
In many (most: probably 9/10 times) cases, a switch statement can be replaced with a registry object.
This cleans up the ugliness of the switch and also allows you to add and remove behaviors as needed, without changing the internals of the registry or the code that is calling the registry to get things done.
The Registry Object
This code gives you all the features you need to completely replace a switch statement, including default values (though, not including fall-through switches, which are a bad idea to begin with).
I Need More Cowbell
Being able to swap out a switch statement with a registry object is great. But what if you want to know why the registry was built the way it was? What if you need more cowbell?
If you’re looking for info on how to build a registry, and why you would want to build it the way that I’ve shown, then checkout WatchMeCode Episode 14: The Registry Pattern.