In The Pragmatic Programmer, Andy Hunt and Dave Thomas talk about software entropy and the broken windows theory. The premise of the broken windows theory was introduced in an article from The Atlantic in 1982:
Social psychologists and police officers tend to agree that if a window in a building is broken and is left unrepaired, all the rest of the windows will soon be broken. This is as true in nice neighborhoods as in rundown ones. Window-breaking does not necessarily occur on a large scale because some areas are inhabited by determined window-breakers whereas others are populated by window-lovers; rather, one unrepaired broken window is a signal that no one cares, and so breaking more windows costs nothing.
Applied to code, the idea is that the more bad code that exists in a code base, the more acceptable it is to keep adding bad code. Projects that tolerate the small, annoying stuff are more likely to rot over time.
First Impressions
When a new developer joins an existing team, the first few hours can set the tone for the entire project. Does the developer come in and immediately see that the project is in disrepair? Consider the following steps a new developer will take when ramping up. They need to:
- Get a copy of the code
- Set up databases and other external dependencies
- Install project libraries
- Run tests
- Run the project locally
Without even reading the code, new team members have a chance to form a strong opinion of the project by seeing how much graffiti is on the walls. A project that is hard to set up will be more difficult to work in than one that is easy to set up.
Fortunately, the problems are easy to identify, and relatively easy to fix. Here are some of the most common problems I've seen, along with suggestions on how to address them.
Project Setup Requires an Actual Wizard
If the setup time for a new developer can take the better part of a day, there are probably parts of the process that can be automated. This could mean installing a new database, a search tool, a messaging system, a PDF generator, and so on. Getting the right versions of all of these tools installed and configured can be a cumbersome process.
Recommendations:
At a minimum, write a good README that details the steps needed to get up and running.
Even better, create a few rake tasks or scripts that can automate the setup process so getting started just takes a few commands. If you are doing more than 'git clone && rake', then you can cut down on your setup.
If the machine setup is very complex, maintain a developer VM with a tool like Vagrant or Github's Boxen.
Noisy Tests, Spam in the Log Files
Noise in a test suite can be easy to tune out after a while, but it's glaring for the developer running the suite for the first time. There could be deprecation warnings or output that is going to the command line instead of a log file. There could be pending tests, or even failing tests (then you're particularly screwed).
It's amazing to me to come on to a project and see that this output has persisted for days, weeks, even months without anyone taking the time to address the output. What are those deprecation warnings anyway? Why are we logging to sysout instead of somewhere trackable? Why were the tests pended to start with? Who checked in the failing tests and why do they still work here?
Recommendations:
When you get test output that isn't a bunch of green dots, or your development.log file is cluttered with warnings and confusing output, FIX IT! Take the suggestion to stop using a deprecated method. Use the proper logging mechanisms instead of printing to sysout. Fix the pending test, or delete it if it's no longer needed. Do whatever it takes - just don't let it sit there.
Sloppy Dependencies
Dependency managers (pom.xml, Gemfile, etc) are also common spots to find broken windows. Overlapping and unorganized groupings of packages, dependencies that have been commented out for months (or years), and dependencies without minor versions specified can make it difficult to track down the last known working version of a library that the system depends on.
Recommendations:
Organize your dependencies into a well-formatted, consistently grouped file. Lock your minor versions to avoid accidental upgrades.
If you're using Ruby, try out the pessimize gem. It will do its best to clean and organize your Gemfile into something resembling sanity.
Clean It Up
It can be very discouraging to join a team and see that these very common problems have been ignored over time. It's never too late to turn it around, though. As Uncle Bob says in The Clean Coder:
We’ve all seen code rot and degrade as time passes. So we must take an active role in preventing this degradation.
Instead of discouraging new team members, make it easy to follow the Boy Scout rule and leave things a little better than you find them by keeping the big stuff clean. This will set the tone for all new members, and it will encourage the team not to tolerate broken windows.
Resources
Martin, Robert C. (2011-11-10). The Clean Coder: A Code of Conduct for Professional Programmers
Hunt, Andrew; Thomas, David (1999-10-20). The Pragmatic Programmer: From Journeyman to Master
Kelling, George L.; Wilson, James Q. (1982-03-01) "Broken Windows: The police and neighborhood safety" - The Atlantic.