Inflation of comments
When I started to program professionally, more than ten years ago, I felt it was pretty hard for me to get into others' code. I was having a hard time reading it. I wanted to make sure my code wouldn't look like that. So, as we often do, I made sure my code was filled with tons of comments. Let me demonstrate with an example (code taken from my refactoring hands-on post, comments added for this post):
That's not the whole class but it pretty much reflects the idea. Now, take a second and try to figure out what this code does more or less.
I bet you didn't read the comments. And if you did, that's only because I have been writing about comments from the beginning of this section. Most of the times we are blind to comments, we ignore them. Especially if there are many of them and we're already used to them stating the obvious. Do I really need a comment stating that this is THE item Dao?
All of the comments in this code are pretty much the same, stating the obvious. This is not readable code, this is cluttered code that needs to be maintained twice - once for the code itself and once for the comments. Problem is - comments tend to rot. We don't have to maintain them, the computer doesn't care what they say, the computer only cares about the code. So, we tend to neglect them. I bet most of you didn't even find the copy-paste mistake hidden in the comments.
Deflation of comments
After I realized that I was inflating comments, I started to deflate them. I wanted my code to feel that when there's a comment, it must be read, it's important. I eliminated all of, what I call, "The Duh" comments.
I only added comments when I really needed to explain what I was doing. For example, what I like to call "The eeeefff if" (because it's such a code-smell):
No way you can understand what this if-clause checks on the first read. You'll have to read it at least twice, and usually 3-4-5 times, to be certain you understand the code. In this kind of scenarios I had usually put a comment that stated what this clause was supposed to do: "Checks if the document has a title or if we can extract a title" (for the sake of the example - let's assume we can extract a title from video/image). Ok, that's a bit clearer now, but we need to consider two things:
- People will still, most likely, try to read the code before the comment (assuming they won't ignore it completely).
- Even after reading the comment, it is still not clear why we are so certain we can extract a title. The if is complicated, and we can't be sure the comment is aligned with the code and hasn't rotten yet (at least without checking the source-control history).
We'll get back to this example later.
/* No comment */
At the last stage (so far...) in my journey for writing readable code I realized, with the help of Uncle Bob in his book Clean Code, that I should make my code readable without comments. This may sound extreme at first, "A code that is readable without any comments?", well... yes. Aside for some very specific cases, you should aspire to avoid comments in your code and just write code that is readable on its own.
Writing code in English
If you manage to write code with each line looking like a sentence in English, each method is a paragraph telling about a very specific subject of the big picture, and each class tells only one aspect of the story - you will not need almost any comments, and your code will be readable. And also as a beneficial side effect, well-designed and maintainable. Uncle Bob compares this type of code to a newspaper where you have articles (classes) with headers (high-level method abstraction), sub-headers and text which both represent different levels of implementation details.
The two main ways in my opinion to achieve such code are:
- Descriptive naming
- English-like sentences
Descriptive naming
There's just so much to say about descriptive naming which makes it a topic for another post. I'll just give a few pointers for good naming:
- Give clear descriptive names which can be used in English-like sentences (will be described in the next paragraph)
- Avoid using abbreviations
- Stick to conventions
- Avoid making the reader scroll up/down the page to figure out what a variable/method/class is meant for. With good naming, usually no scrolling will be needed.
Giving names to things is amongst the programmer's most difficult tasks. I suggest that when you write the code, start with any name (even foo for a method), and improve it as you go along (but before you commit or ask for review).
English like sentences
Try to maintain the reading flow of your code-lines. Make them look like English sentences. For example:
You can read the if sentence like an English sentence "if store has client - currentClient". That is far more readable than doing something like:
The same goes for the ugly "if" we saw before. We can extract it to a private method in the Document class that simplifies the question in a form of an English sentence "if doc has title":
The Document object will encapsulate the answer to the question by calling two private methods that each simplifies another aspect of the question:
You can read the if sentence like an English sentence "if store has client - currentClient". That is far more readable than doing something like:
The same goes for the ugly "if" we saw before. We can extract it to a private method in the Document class that simplifies the question in a form of an English sentence "if doc has title":
The new if form |
The Document object will encapsulate the answer to the question by calling two private methods that each simplifies another aspect of the question:
Each part of the question is simplified in its own method |
This way completely abstracts for the readers the question "has title?" and its two sub-questions - "already has a title?" or "can a title be extracted?" The proximity of the methods in the code also counts, but I won't get into that in this post.
Is it ever ok to use comments?
Of course! Comments are needed for java docs, they are needed to explain a nasty hack, explain why you preferred one algorithm over the other (when it's not obvious) or add a TODO comment (but if it stays there for more than a few days - it's also a code-smell). Also, each rule has its exception and sometimes comments may be needed to explain the code. But try to make it the exception, and not the norm, to use comments to explain yourself.
Further Reading
This post was longer than most of my posts and I haven't even started to scratch the tip of the iceberg on the subject. I invite you to read Uncle Bob's Clean Code in order to improve your code-writing skills. Also, don't hesitate to contact me (via Twitter, Linked-in or just leave a comment here) for more help on the subject.
I also invite you to send me code examples with explanation comments (even if we don't know each other yet) and we'll try to figure out together how to remove them and create a clean, readable code instead.
Find me on Twitter: @AviEtzioni
More interesting posts from this blog:
Some people criticize uncle bob for over simplifying methods see this
ReplyDeletehttp://vimeo.com/49484333
P.S
I don't necessary agree with her but sometime creating a method with one line is too much
Thanks for the link - very interesting. And, of course, I'm no stranger to criticism to Uncle Bob's over-simplification.
ReplyDeleteI think everything should be done with good taste. I did agree with her when she said that hiding s**t inside a method name is nasty. Instead - refactor to make it look better and designed better.
Also - if you're keeping your classes small (I rarely hit the 200 hundred lines when I write a completely new code) you get very small and testable units. In such small classes, you don't have to over simplify because there's so little going on. That's another aspect of readability I think. But this blog is too short to write a new "Clean Code" so I just gave a taste of what I think :)
This comment has been removed by the author.
ReplyDeleteGreat post Avi, thanks!
ReplyDelete:)
For the sake of accuracy, I would suggest to change && to || in Document.canExctractTitle().
Thanks for your reply. But look again at the original demonstration - it contains 2 AND conditions (each with parentheses) that are combined with an OR condition. I extracted each AND condition to its own method and a 3rd method calls the 2 AND methods with an OR. So, we're good :)
DeleteGot it :)
DeleteI have read all the comments and suggestions posted by the visitors for this article are very fine,We will wait for your next article so only.Thanks! Chinese translation
ReplyDeleteHi Farhan, thank you for your kind words. I no longer post new posts in this blog so don't wait for too long :)
ReplyDeleteI felt very happy while reading this site. This was really very informative site for me. I really liked it. This was really a cordial post. Thanks a lot!. Best Laptops For College Student:2019's Buying Guide
ReplyDeleteThanks for taking the time to discuss this, I feel strongly that love and read more on this topic. If possible, such as gain knowledge, would you mind updating your blog with additional information? It is very useful for me.
ReplyDeletecs代写
I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often.
ReplyDeleteitcs代写 质量
Nice post! This is a very nice blog that I will definitively come back to more times this year! Thanks for informative post. Best laptops review
ReplyDeleteNo doubt this is an excellent post I got a lot of knowledge after reading good luck. Theme of blog is excellent there is almost everything to read, Brilliant post. weclub88.cc
ReplyDelete"Thank you for exploring all aspects of Java! Your dedication to learning grows our group's progress. Keep in mind that software company Chennai community is always available to assist you as you navigate the world of Java. May your Java travels be as exciting and varied as the tech location in our city, and happy programming!"
ReplyDelete