Many of you will probably not agree with me, but if you read all this post, you will probably agree that commenting your source code is a sign that your code sucks. Real men write code that other people can read!
But keep in mind that I’m talking about comments that tell what the code do, and not documentation like “Javadoc”.
For example, if you ware not a Java programmer, or even being a java programmer, can you quickly tell what the code bellow do?
1 2 3 4 5 6 7 8 9 10 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
Hard one? And this is a very simple code, but we can make it a little better …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public String read(StringBuilder fle, StringBuffer con) { //Opens the file with the name container in the fle parameter File f = new File(fle.toString()); //Create a file reader, then a buffered reader to make our work easier FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; //Read each line of the file until it is null while((lin=br.readLine())!=null){ //Put the content read into the buffer pointed by the parameter "con" con.append(lin).append("\n"); } //The caller already have the content, because he created the buffer, but I'll return the string anyway return con.toString(); } |
Easier, right? Now you can read the comments in the code, and understand it, but the code still crappy.
This is the kind of comment I’m talking about. Commenting your code is a sign that you are a very bad programmer (with little exceptions, in very complex algorithms that you can not break in smaller pieces of code).
When you do this, you are doing a “hack” to hide from others your own incompetence. This mean that you cannot write a clearer code. One that other programmers can read.
Here we have a little solution for the code above, a refactoring of that crappy method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public String readFileContents(File fileToRead) { boolean canReadFile = fileToRead.exists(); if(!canReadFile) return ""; StringBuilder buffer = new StringBuilder(); BufferedReader readerForFile = openBufferedReaderForFile(fileToRead); readFileContetIntoBuffer(buffer,readerForFile); closeFileReader(readerForFile); return buffer.toString(); } private BufferedReader openBufferedReaderForFile(File fileToRead){ return new BufferedReader(new FileReader(fileToRead)); } private void readFileContetIntoBuffer(buffer,readerForFile){ String line; while((line=readerForFile.readLine())!=null){ buffer.append(line).append("\n"); } } private void closeFileReader(readerForFile){ readerForFile.close(); } |
Now if you pay attention to the method name “readFileContents”, you can already know what it does, besides that, the method code is almost legible, as you can see bellow:
if not can read file, return null
open Buffered Reader For File: fileToRead
read File Contet Into Buffer: buffer, readerForFile
close File Reader: readerForFile
return buffer.toString();
What I’m telling is that if you can read english, you can read the code, and almost every programmer in the planet knows how to read english, right?
I have even seen people doing worst things, like the snippet bellow:
1 2 3 4 5 | public String write(StringBuilder fle, StringBuffer con) { File f = new File(fle.toString()); FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String lin; while((lin=br.readLine())!=null){ con.append(lin).append("\n"); } return con.toString(); } |
It has less lines of code than my version, but you will have a hard time trying to read a program wrote by the monster that wrote the snippet above.
Of course the example I used was a simple one, and I know that writing legible code needs practice …
But I’ll let you a proposal, not really a proposal, an exercise …
I’ll let a code example bellow, and you will try to make it more readable. And I’ll post my solution in one or two days.
If you want to post the refactored code in the comments, just use the tags <pre lang=”java” line=”1″> … </pre>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package blog; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class VeryBadlyNamedFile { private static final char[] asdfg = new char[] {'I', ' ', 'c', 'a', 'n', ' ', 'd', 'o', ' ', 'v', 'e', 'r', 'y', ' ', 'u', 'g', 'l', 'y', ' ', 'c', 'o', 'd', 'e'}; private String an; private BufferedReader rfsdw; private FileReader temp; public VeryBadlyNamedFile(String an, BufferedReader rfsdw, FileReader temp) { super(); this.an = an; this.rfsdw = rfsdw; this.temp = temp; } public void doIt() throws IOException { ctfiidne(); startDoing(); try { canIDoAnyThing(); } catch (RuntimeException yicdet) { nowReallyDoIt(); } } private void nowReallyDoIt() { firstDoTheOtherThing(); reallyDoItInternal(); } private void firstDoTheOtherThing() { rfsdw = new BufferedReader(temp); } private void reallyDoItInternal() { while (true) { try { imDoingIt(); } catch (Exception e) { break; } } } private void imDoingIt() throws Exception { String s = rfsdw.readLine(); if (s == null) throw new Exception("hahaha, I bet you did not understood the code"); System.out.println(s); } private void ctfiidne() throws IOException { File a = new File(an); if (!a.exists()) { FileWriter wrfedsd = new FileWriter(a); wrfedsd.write(asdfg); wrfedsd.close(); } } private void canIDoAnyThing() { if (new File(an).exists() && new File(an).canRead() && new File(an).canWrite()) throw new RuntimeException(); } private void startDoing() throws FileNotFoundException { File f = new File(an); temp = new FileReader(f); } } |
And now a “main” file to exebute the trash above.
1 2 3 4 5 6 7 8 9 | package blog; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { new VeryBadlyNamedFile("c:\\anyFile.any",null,null).doIt(); } } |
The examples in this post are using Java, but the concept apply to any language, if you are programming and using comments to explain your code, you are a terrible programmer. Just pray for god’s help, and beg him that the next one to read the crap you are creating is not a serial killer that knows where you live.
PS.: I really do not think that you should not comment your code, but if your code is not understandable without the comments, you do not know how to write programs yet.
PS2.: I think I need better examples.
PS3.: the secret to write good code is to write it as if the next one that will read your code is a serial killer that knows where you live. (I do not remember who wrote this sentence in the first place, I’ll research and post it here)
If you enjoyed this post, make sure you subscribe to my RSS feed!
I think it’s a good practice, but sometimes there are limitations, by the way I don’t be clear with the last phrase, what it means?
Reply to this commentGood article. I agree that it’s important to use meaningful variable names and give each instruction its own line so that others can understand what your code is doing simply by reading the code.
Where comments come in most handy is not explaining WHAT you are doing, but explaining WHY you are doing it. Often the WHY cannot be deduced simply by reading the code, and in these cases comments are essential.
Reply to this commentJavier, sorry for my bad english, I need to study more.
)
The phrase is corrected now (I think it is
DevTopics, I totally agree with you, but I think that people need to learn not to comment first, and only then, they can learn to comment right
Reply to this commentOh great, another blogger that doesn’t understand the how/why distinction. Here’s a code snippet:
request.Description = description.substring(0, 30);
That’s easy to read, right? Easy to see what’s going on, no need to add a comment, right?
Then you get a change request to truncate the description at 40 characters because some information is being lost. How do you know that won’t be a breaking change without knowing WHY the current truncation is at 30?
Now imagine there’s a simple one-line comment:
// 3rd-party binary wire protocol has 30-char limit
Aha! Now thanks to the consideration of your predecessors, you have the information you need, saving you hours of traipsing through layers of code and interfaces to 3rd-party systems.
Comments are for explaining why things are done, not for restating how to do something.
Reply to this commentRuss, I just agreed with “DevTopics” exactly on what you have wrote here.
Reply to this commentI agree that commenting WHY you are doing something is good, this post is about when the comments are telling HOW you are doing something. Of course it is being done in a very aggressive way, but I totally agree with you.
@Russ:
No, no, no.
The _first_ thing you should do is fix the code.
Define 30 as a constant with a meaningful name like “XProtocolCharLim”.
Now you can start thinking about whether an additional comment is justified.
Reply to this commentOh, man! This post seems to miss the point a bit.
Comments are not for describing “what” happens in a particular piece of code, but about “why” it’s coded the way it is.
Of course, if you begin something from scratch, it’s up to you to design it in a way, that javadoc comments suffice to describe the “why” in most of the cases.
In reality, it happens that you get assigned to work on less optimal designed software, where you are happy if some comments describing the “why” exist, or where you are not given the time to refactor enough and hence have no better choice as to resort to comments when improving code readability on the fly…
Reply to this commentPS4: You should learn ENGLISH!!!!!
Reply to this commentI agree with only using appropriate commenting. I usually assume that if someone is reading my code, they can understand what the code is doing in general if they have an idea of what it is supposed to do. So I usually simply have comments for larger sections of code, or for functions, that say something like “Read the file in and store it in the stringBuffer con”. But I would agree that commenting every other line is a waste of your time, I think a comment like “//Open the file” is (almost) never necessary.
Reply to this commentJörg, this post is not missing the point, it is talking about how comments are used by many programmers on the market.
Reply to this commentAnd I’m stating that these programmers, that use comments to describe what the code do, are losers.
Brett, if you have this kind of comment, you need to read the post again, and stop commenting.
Reply to this commentIf the comment says what the code do (like in your example “Read the file in and store it in the stringBuffer con”), the comment is wrong, it should not say what do code do. Why it is done is OK.
Of course if this is a javadoc comment, it is documentation for some one without access to the source code, then it is OK.
lonestranger,
Reply to this commentI’m studying,
And I’ll thank you if you are kind enough to point my errors.
Please people, what’s going on!, is this a blog for learn something? or some kind of “I’m better than you!” blog, a little of respect for our points of view is required, just my humble opinion.
Reply to this commentWhile I can sort of agree with your overall message, this was not a very good example. Looking at the first code block, it was very apparent to me what that code did (aside from naming the function/method “write;” what is being written?). I do agree that the comments in the second example are completely overboard. However, your third block is just ridiculous. An operation as simple as reading data from a file and into a buffer is not complicated enough to warrant being broken up into 4 separate functions (unless the specific app/project you are working on has use for those individual functions in another context).
Over-commenting is unnecessary, certainly, but restructuring your code and making it needlessly complicated when some comments will suffice is even worse.
Reply to this comment