We as programmers like to think otherwise, but we are by no means perfect. We do make mistakes all the time. One of the most important traits of a good programmer is to recognize this and, more importantly, to act upon it.
If one takes on a development endeavor there is one obvious path that also happens to be the most error-prone. It is this path: you have an idea, you code, you startup your app, click through it once and you’re finished. Although this path might seem productive in the short-term it will track you down and bite you in the long-term.
The root of many (most?) errors in software are false assumptions. We think we have coded something the right way, but often it is not. The first step to increase the quality of your software is to recognize your assumptions. The second step is to check and double-check them.
We can learn from accountancy here; every accountant in the world uses double-entry bookkeeping. Why? Because it is a fast and easy way to catch most errors. Accountants know that the costs of the effort put in the double check is neglectable if compared to the costs of potential mistakes in the results. It is an effective idea and we as software developers should learn from this.
So, what can we do to double-check our code? How can we as software developers test our assumptions in design and code?
Code, thus assumptions, is double-checked when it is read by more than one person. Pair programming might be a good fit here. But in many shops this is not (yet) a daily practice. So, what to do if you are a single programmer hacking your way through. The solution: expose yourself to your code from different perspectives.
Here are some more ways to double-check assumptions:
- Write unit tests. Test more than just the happy path. A true TTD practionist develops test first and thereby forces itself to think about design before, while and after the implementation. That is triple-entry bookkeeping.
- Use a programming language with a strong typing system. Dynamic languages have their advantages, but statically typed languages force you to think twice about assumptions. One time when you declare, a second time when you implement.
- Try mentally explaining your design to your colleague, friend or mother.
- Write out your design on paper. Use a mix of natural language, code and visuals.
- Write pseudo code before your implement your code.
- Write down commentary before and while you are coding. However you can delete most of it afterwards; good code should be pretty self explanatory.
- If your language supports interfaces, consider using them more intensively. Interfaces force you to focus more on design rather than implementation.
- The first time you execute your code, go through it step-by-step with a debugger. Does it really flow as you though it would?
This is by no means an exhaustive list. I’m sure you can think of many more. But the concept remains the same. A good programmer is humble and recognizes it can fail. It knows that the righteous path means measure twice, cut once.