7 Rules on Code Readability

What makes good code? Many things but whatever the qualities are, readability is a cornerstone.  If you can’t read the code, you can’t fix it. So how do you write readable code? I’ll give you my view but it’s like books, what I find enjoyable may be different from you.

1. Rewrite what you wrote

When you first solve a problem, you’re focused on the problem solving.  That seldom results in readable code. If you immediately rewrite, you still have a deep understanding of the solution and are thus in a optimal position to do it.

2. No comments

Avoid comments. If you’re not allowed to use comments, you force yourself to write readable code. This is a bit controversial but comments have drawbacks.  They have a tendency to rot. An outdated comment is far worse than no comments at all, since it will just confuse the reader.

APIs are a different thing though, as comments are used to create documentation for readers that do not necessarily have access to the implementation. But that’s not comments, that’s interface documentation.

Don’t use comments to make up for unreadable code.

A colleague mentioned to me that some comments are marked TODO and used to organize your work. Of course you can use them! Just don’t leave them around. But of course you always finish you work properly so that won’t happen, right?

3. Good Names

Names should be short, to the point and not cryptic.  The reader is in a context so don’t repeat in every name.  Cryptic abbreviations should be avoided, unless well established like PDF.

If lines get too long due to long names, readability drops. Too short names risk getting cryptic.

Use type inferred variable names only if they are the only one of that type in the context.

// Bad
Car car = foo()
Car previousCar = bar()
// Better
Car current = foo()
Car previous = bar()

Too detailed naming conventions tend to stir up heated debates. Keep an open mind and try to understand why people feel different than you. The main thing is readability and although you may believe so, no static code analyzer can verify readability of names.

Another thing that you may find controversial, is how I like to name test methods. I’ve given up on camel case and switched to underscore instead.

// CamelCase
public void givenAPeerReviewTestWhenAtHandInPageThenHandInBlankButtonIsInvisible() {
}
// Underscore
public void given_a_peer_review_test_when_at_hand_in_page_then_hand_in_blank_button_is_invisible() {
}

My motivation here is that is not a name, it is a sentence.

4. Extract nested loops

Nested loops never reads well, avoid them. Extract the inner loop into a new method.

5. Maximum 7 lines

Methods should be no longer than 7 lines long, preferably even shorter.  If you break this rule,  you present too many details to the reader at once.  Only count lines that adds to the cognitive overhead, not empty lines or lines with a single brace.

Extract chunks of code into new methods and name them well. Every method should have a single responsibility so watch out for names with “and” in them.

Tip: prepare for ‘extract method’ by changing order of statements. Consider:

firstCar.setSome(x);
secondCar.setSome(y);

firstCar.fixAnother(z);
secondCar.fixAnother(z);

The above is in chunks of methods, making it hard to do the ‘extract method’ refactoring. Change to the following:

firstCar.setSome(x);
firstCar.fixAnother(z);

secondCar.setSome(y);
secondCar.fixAnother(z);

Now you can extract a method from the first two lines and call it twice instead.

6. Formatting

No, you can’t have your own formatting rules and I shouldn’t need to tell you why. Just apply the agreed upon formatting as often as possible.

And remove those empty lines you created when trying to think. 🙂

7. If you can’t read it, rewrite

If you can’t read the code, it should be rewritten. If you’re not covered by tests, that’s a bit risky, even if you use your development tool’s support for refactoring.

The process of rewriting the code increases your understanding, regardless if you check-in the rewritten code or not. But if you do, check-in the readability fix separately from other changes.

Quite recently I rewrote some code containing long methods and no tests. Of course I introduced a bug.  Lesson, if you have no tests, do not check-in your rewrite.

Epilogue

These are just my thoughts, but it pays off to consciously think about what you believe makes code readable. What are your rules? Write them down like I did here! Show them to someone and discuss.

8 responses on “7 Rules on Code Readability

  1. Here is my old list of basic code hygiene checks.

    #0 Make sure it works (encapsulation and automatic tests may come in handy)
    #1 Rename classes, methods, parameters and variables to communicate intent of the code
    #2 Replace comments with self-explanatory code where possible
    #3 Keep methods short
    #4 Remove nested conditionals (e.g. if, for, while) and replace conditionals with simpler code when possible
    #5 Remove duplicated code and duplicated logic
    #6 Put responsibilities in the right place
    #7 Remove unused and unnecessary code

    I often enjoyed searching ways to get #2 and #4 done where others thought it was impossible 🙂

    Luca

  2. Every year I drive my students crazy with code critiques, all along the lines of your list. The most common critique categories, roughly in order of frequency of occurrence:

    Function too long
    Name vague
    Code repeated
    Indentation misleading
    Comment clutter

  3. I disagree with the 2nd point. It tries to convey that instead of writing $a = 12; you should write $monthsInYear = 12; This is fine, you shouldn’t use comments here, instead name variables accordingly. But comments are invaluable for providing *context*: WHY was the implementation done the way it was? Did the author try another approach and it didnt’ work because of X? Was there a business rule or a ticket that said to do it exactly so? *Do* write comments to explain the WHY, not the WHAT.

    1. I used to think that “why” is an argument for a comment. But then again, those comment rot too. And it is horrible when a comment seems to refer to a business rule that has changed and you can’t really be sure if that change makes the code invalid.

      With unit tests, integration tests and specification by example, the comments that tell the “why” should also be redundant.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.