In the old days (like about 3 years ago), I used to comment my code quite a bit. These days I don’t; it’s rare that I write a comment. Why? Here are some possibilities:
- I’ve got lazy in my old age.
- I inadvertently made comments display as white on white so I can’t see them any more. Why write them if I can’t see them?
- I’m of the firm belief that anyone who has to read my code has to be a Zen master. Since Zen masters reach an understanding of code that’s far deeper than mere mortals, it would aggravate them to have one-liners explaining it all.
- I’m so paranoid about the meaning of my code and comments drifting apart that I dare not write comments any more.
- My code is now so simple it doesn’t need explanation. It is "self-documenting".
Now, I’m sure you’re all putting up your hands saying "Number 1". Wrong, sorry. Of these possibilities, the answer is the last one, number 5. To which I’m sure there are some who are saying "Yeah, sure, that’s an excuse for number 1".
But consider this. I love using refactoring tools to organize my code (I’ve been using C# Refactory for a long while in VS, and am just getting to know Delphi 2005′s refactoring tools). I write my code in a Test-Driven Development (TDD) manner. I think and design and write in small steps with unit tests to make sure I don’t go astray.
My code is naturally simpler than I ever used to write.
But what’s that to do with writing comments? Think about why you need to write comments. Perhaps you have a long method that’s difficult to grasp as you scan it (maybe it’s so long that it goes over several pages on the screen). In that case you have to write comments as some kind of "headers" within the "text" so that it breaks up the flow into manageable chunks, much as a book is divided into chapters, or an article is divided into sections.
In that case, I’d have to say that the method is too long. It should be broken up into smaller methods, into separate classes, or whatever. I’ve just written an article for The Delphi Magazine that explores how to break up a state machine written as a huge case statement with a case block per state. In the article, I describe how to break the code up into into several classes, each of which is simple to understand. Martin Fowler, in his book Refactoring, explores strategies for changing such code.
In long methods, the comment that describes the functionality of a block of code indicates that the block of code should be a separate method. A comment like "// Print the header block" which is followed by a bunch of code that prints the various parts of a header should be extracted to a new method called PrintHeaderBlock. Suddenly the method name describes what it does and the comment is superfluous. This is a simple example of self-documenting code.
Sometimes comments explain what a method does. I’d counter with either (1) the method is badly named (compare with the previous refactoring), or (2) the method does too much — it does several things, each of which should be done by a separate method. In fact the "badly-named method" is a very common error, or anti-pattern.
So when do I use comments?
- To explain an algorithm that may be obscure.
- To explain why a funky bit of code is used instead of an expected implementation. This can happen when the funky code is more efficient.
- To explain what fields are used for (although this could fall under the "bad-name" exception), what the items in an enumeration are used for, and so on. In general, though, I avoid them.
Take a look at your code. Are you explaining your code in comments instead of refactoring your code to something simpler so that it becomes self-documenting?