Conditional branches are like a piece of meat in the source code; as the software ages, the meat starts to rot. Before you know it, maggots (bugs) will start to feast on the meat.
One of the main reasons bugs tend to hide around conditional branches is because it increases the complexity of the software. The more conditional branching exists, the more difficult it is to fit all the logic into one’s head. This is obvious, and I can probably talk all day on how bugs can be introduced with conditional branching, but let’s not dwell on that. Instead let’s talk about how we can solve the problem in a simple way.

The dispatch table pattern is not new, but I feel like it is not widely adopted. It is not a traditional design pattern one will find in a typical design pattern book, but in my opinion this pattern will give you the most bang for the buck. With a dispatch table, branching statements can be eliminated completely, and the “shape” of the code can be seen. In the simplest form, a dispatch table is a hash table where all the keys represent all possible actions, and the value of each key contains a call back function that does the actual work.
This is best explained with a simple example. I am going to use JavaScript in the example, but the idea is language independent.
Let’s say, you are building a Tivo’ish program that surfs all the channels and figures out what it should record. Assuming an external data feed look like following:
var channels = { 1: { station: "NBC", showTitle: "Saturday Night Live", genre: "comedy", repeat: true }, 2: { station: "FOX", showTitle: "Cops", genre: "crime", repeat: true }, 3: { station: "ESPN", showTitle: "College Football", genre: "football", repeat: false }, 4: { station: "HBO", showTitle: "Curb Your Enthusiasm", genre: "comedy", repeat: false }, };
The key for the channels hash table is a channel number. In this case, there are only 4 channels, one through four. Let’s move on to the core logic:
function record(channel) { // do some work here... console.log("recording " + channel.showTitle); } function surf(channels) { var genre, repeat, showTitle; for(var number in channels) { genre = channels[number].genre; repeat = channels[number].repeat; showTitle = channels[number].showTitle; if (genre === "football") { record(channels[number]); } else if (genre === "comedy" && !repeat) { record(channels[number]); } else if (genre === "crime" && showTitle !== "Cops") { record(channels[number]); } } }
The code above is making decisions on the genre of the show with a couple of ugly else-if statements. As one can imagine, the else-if statement will continue to grow when additional functionality is required and eventually becomes unmanageable. Imagine what the unit test for this function looks like. Yuck!
Now let’s switch to the dispatch table version:
var actions = { "football": function (channel) { record(channel); }, "comedy" : function (channel) { if (!channel.repeat) { record(channel); } }, "crime" : function (channel) { if (channel.showTitle !== "Cops") { record(channel); } }, }; function surf_dispatch(channels, actions) { var genre; for(var number in channels) { genre = channels[number].genre; actions[genre](channels[number]); } }
An actions dispatch table has been added as a parameter, and all the conditional branch logic has been completely removed. Notice how simple the new surf function has become. Now this version is very easy to extend because the application logic has been decoupled from structural logic. To make things even better, the actions dispatch table is essentially a configuration point for the application. There is an anonymous function with one parameter associated with each key, that is the interface each dispatch item must implement. The application will start to behave differently when the table has been updated. New behavior can be injected without changing any core code. Now, that’s flexibility!
Skeptics may say, that problem has been solved in the Object Oriented world by polymorphism. There are known refactoring steps to deal with this: Extract Method, Move Method, Replace Type Code with Subclasses then finally Replace Conditional with Polymorphism. Wow, that is a lot of work, and think about the number of classes and lines of code you will end up with! I will take the dispatch table pattern any day.
Dispatch table is one of those hidden gem design patterns, that will allow the software to be extended in ways never imagined. The application behavior can be completely changed by supplying new anonymous functions to the dispatch table. If you are working in a dynamic language, the dispatch table can live in a separate “configuration” file, and be read during run-time.
I have only scratched the surface on what you can do with a dispatch table. Chapter 2 of Higher-Order Perl by Mark Jason Dominus has a much more comprehensive overview of dispatch tables. The book is currently available as a free download, so there is no reason not to check it out. Don’t be afraid if you are not familiar or a fan of Perl, the book is readable with very little Perl knowledge.
I would also like to give a special thanks to my friend, and colleague, Kyle Burton, for recommending the book. It forever changed how I think.




