Many developers hate documenting their code: They view writing comments a nuisance, something that slows them down. All they want to do is get the darn code to run; comments just mess-up the code and — behold! — are for wimps, anyway.
Sometimes even followers of this school of thought write comments, but these comments are frequently a mixture of self-indulgence, inside jokes or just plain insults:
1 2 3 4 5 6 7 8 |
// What a coooool macro! ... // Don't even try to understand this. ... // Kill those suckers. ... |
Then there are folks who take the exact opposite position. They want comments everywhere. They believe that comments should be of such a density, that by just reading the comments they would get a perfect understanding of the whole system. Never would they have to look at such ugly things as — behold! — source code again.
Like it or not: I have observed that many of the highly gifted developers belong to the first group.
But let’s face it: neither position is right. As professional software developers we need to understand that we have an obligation to preserve the value that we create. Good comments do help understanding the code and thus improve maintainability and we are in maintenance mode most of our lives. Like the old saying goes: “Be nice to the next guy”; and often that next guy is you (or me).
On the other hand, crafting good comments is hard and time consuming and as professional software developers we also have an obligation to spend the resources of our companies or clients prudently. Therefore, we need to strike a balance: sometimes it is best to leave the nitty-gritty details for the code.
My rules of thumb so far have been:
1. Focus on good layout and self-explanatory identifier names.
2. Explain the WHAT and not the HOW.
3. Comment surprises; that is, unexpected/unusual things.
4. Comment all non-private parts (public, protected, default)
5. The more public, the more detailed the documentation has to be.
I used to defer writing API documentation comments as long as possible. My reasoning was that otherwise I would have to update/rewrite the API documentation while iteratively developing my code, which I considered a big waste of time and energy. But I’ve changed my mind completely in this respect.
I strongly believe that writing the API documentation before doing any coding is a great benefit. By clearly spelling out the purpose of a piece of code, developers engage in a brainstorming session with themselves that leads to further insights. Until this purpose cannot be stated concisely there is no point in doing any coding. Let me repeat that: If you cannot crisply describe WHAT a method or class is supposed to do, you shouldn’t start implementing it. Granted, most developers do have at least a partial model in their mind before they start coding. If they would also write it down, they could win in several ways.
Naturally, even API documentation comments need to be developed iteratively and often need some fine-tuning during the course of implementing the API. In fact, the process is very similar to test-driven development: One of the biggest benefits of TDD is that by writing tests before doing any coding, you imagine (and in fact see and experience) how the interface is used by clients early on; that’s valuable feedback which helps getting interfaces better. The same holds for the WHAT of a method or class as well.
The notion of writing comments or documentation before doing the coding can be extended to the implementation of a routine as well. In his landmark book, “Code Complete”, Steve McConnell describes a comment-first process for implementing a routine called “Pseudo code Programming Process”: You start by typing in the high-level steps that a routine takes, in plain English, using vocabulary from the problem domain:
1 2 3 4 5 6 7 |
Get income If income greater than tax-free limit Calculate tax Deduct tax from income : |
Once your are satisfied with your pseudo code, you fill in the real code. As a final step, you turn the original pseudo code into comments — voilà!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Get income double income = client.income(); // If income greater than tax-free limit if (income > Tax::FREE_LIMIT) { // Calculate tax double tax = Tax::CalculateTaxRate(income) * income; // Deduct tax from income income -= tax; } |
[Note: I know that this example is a little bit contrived. A cooler implementation of CalculateTaxRate() would return a tax rate of zero in case the income is below the threshold. This would result in shorter, branch-free code.]
Writing good comments is essential for every professional software developer. Since writing comments is hard, it is usually left out if it is considered an afterthought, especially under deadline pressure. If it is done upfront, it can serve as a valuable design tool that yields great documentation for free.