Clean Code Matters

In the last post, I mentioned clean code as one of the essential elements of Agile development. So let’s do a little code challenge, shall we?

Our context is a system for managing bets at a race track. The line odds for a race are established in advance, and displayed for the patrons when the betting opens; however, as the bets come in, the odds are adjusted to ensure that the track always makes a small profit. But it turns out that the display isn’t quite working, and the following bug report is filed:

Once betting opens, the line odds are displayed until bets have been made on at least half of the horses. Displayed odds should continue to update, no more than once every twenty seconds. In the current system, once the first update is displayed, the display updates with every bet made, meaning that bettors cannot get a good look at the current odds.

The team has isolated the problem to the handleRequest method of the server, which receives messages from both the betting terminals and the control terminal, and each request undergoes some processing, which may result in a message to the display system. How long does it take you to figure out what is wrong?

This code is probably no worse than much of what most developers work with every day, and most developers could figure out the issue with a bit of study and maybe some experimentation. But this is less than one hundred lines of code, and in a system with millions of lines, that kind of time can be costly.

But what happens if we clean up the code by extracting logical functionality into other methods (not shown here)? That should be a lot easier to read, and I would expect you to find the problem much more quickly. That’s right, the code resets the timer to delay updates only when displaying the betting line odds, and not when when displaying the current odds. Adding that logic fixes the problem.

So what made the original code harder to read than it should have been? First of all, it was too long. Unless you have a very large monitor, you probably needed to scroll the see the entire method, which means that you cannot take it all in at a glance. But that’s just the start of the problems with long methods. The original code was working at multiple levels of abstraction. It was parsing commands, handling domain object updates, managing the update timer, and formatting the display. The revised code delegates much of that to other methods and classes, making each one simpler to understand and maintain.

Almost nobody writes clean code when they initially add functionality. It is typically only after seeing how things work that we can tell what is needed to clean it up — and cleaning up code is a skill that most developers have never been taught. It doesn’t just happen. Now, the best way to learn this skill, like most skills, is by working with a mentor who can teach it and offer feedback, based on his own long experience. Without that, the next best thing to do is to read Martin Fowler’s Refactoring book and practice. You should probably read it anyway, as it is full of great examples and patterns to follow.

You will also need to get into the habit of writing good unit tests, to make this code cleanup happen — but that’s another post.