I finally got around to reading Clean Code by Robert C. Martin (Uncle Bob). It is often high on lists of the best books for software development, and for good reason. Clean Code is an excellent book that all programmers should read. Here is what I liked and didn’t like about it.
The books is divided into four parts. Chapters 1 to 14 go through the basics, including naming, functions, formatting, comments and error handling. Then there are three example programs that are refactored to follow the recommendations given in the first part.
The three example programs are a command-line argument parser, a part of JUnit, and SerialDate, a class for date handling. The examples are quite extensive (together almost a hundred pages), with a lot of source code. All these (and all examples throughout the book) are written in Java.
Next is a chapter called “Smells and Heuristics”, which lists problems in code (and the solutions) in the form of 66 rules.
Finally there is appendix A, with more on concurrency, and appendix B, which has the complete source code for the third example program (SerialDate, almost 60 pages of program listing).
What I Liked the Most
Small. This is the one-word summary of the whole book. Functions and classes should be small (no, even smaller than that). It is much easier to make sure a function does only one thing if it is very small. Dividing the logic up in many small functions also gives you more opportunities to insert meaningful names that explain what is going on.
Niladic and monadic functions. The fewer arguments a function takes, the better (a niladic function takes zero arguments, a monadic one, and a dyadic two). I hadn’t thought much about the number of arguments before, but Uncle Bob makes a convincing case for using very few.
Flag arguments. A flag argument to a function is a boolean argument that controls what should be done. This is really an indication that the function should be split up in smaller parts.
Error handling. The argument for using exceptions for error handling instead of returning error codes is that it is much easier to separate the error handling from the regular logic. Also, using unchecked exceptions (instead of checked) avoids cascading changes when a new exception is added deep down in a hierarchy.
Newspaper Metaphor. The source file should be organized like a newspaper article, with the highest level summary at the top, and more and more details further down. Functions called from the top function come directly below it, and so on down to the lowest level and most detailed functions at the bottom. This is a good way to organize the source code, even though IDE:s make the location of functions less important, since it is so easy to navigate in and out of them.
Javadoc only for API:s. The recommendation is to only use Javadoc for documenting API:s that are exposed externally. Internally in a system, Javadoc documentation usually only results in unnecessary noise. I have seen this problem a lot, and I completely agree with this advice.
Long refactoring examples. The refactoring of the three example programs was quite valuable because it showed how to apply the recommendations in practice, and how the refactorings interact. This is often missing from other books. The disadvantage is that it can be pretty hard to follow when you don’t have an IDE to help you navigate and search.
What I Didn’t Like
Concurrency chapter and appendix. This chapter and appendix felt a bit out of place in the book. I also didn’t like the advice on instrumenting the code to try to find threading issues. In my experience, you don’t find multi-threading bugs that way. Instead, the best way is proper load testing, where the software is in heavy use in realistic scenarios.
Chapters 11 (Systems) and 12 (Emergence). These two chapters, despite promising titles, didn’t contain much of interest. They can easily be skipped without missing out on much.
State to reduce the number of arguments. In order to reduce the number of arguments a method needs, member variables are sometimes introduced instead. While this reduces the number of arguments, it also forces you to examine how the member variable is used in the rest of the class before you have a complete understanding of what the method does. This in my mind is worse, even if the class is small. I prefer the functional style, where it is enough to know the input arguments to have a complete understanding of what will happen.
No emphasis on dynamic error information. When an exception is thrown, it should always contain as much dynamic information as possible, to help in debugging. For example, if a network connection fails, include the port number and IP address the connection was intended for. Without this information, trouble shooting is a lot harder. Unfortunately, this is not mentioned at all in the book.
Wildcard imports. Rule J1 advocates importing a whole package rather than individual classes if two or more classes are needed from the package. However, then your program can break when a class is added to a package you import (more in e.g. this StackOverflow question). A long list of explicit imports at the beginning is not a problem in my view, it is easy to skip over.
There is a lot more good information in this book than I have been able to cover here. You can also tell that the advice is based on decades of experience developing real life software systems. I rate this book as one of the top three books on software development (the other two are Code Complete and The Pragmatic Programmer), and I think all programmers should read it.
Have you read Clean Code? What did you think? How does it compare to other books on programming? Let me know in the comments.
It’s been over a year since I read this book, and I wasn’t impressed. If you write a book on writing clean code you better make sure you don’t write “their” and “it’s” when in the context is should be “they’re” and “its”. Esp. if Enhlish is your native language.
If you want to propagate the use of simple functions with small bodies and descriptive function names, then you shouldn’t write function names that are long and harbour a lot of complexity — I’m referring to looong function names containing the words ‘and’ and ‘not’.
The book has many silly mikstakes (p. 300: Q: “Did you catch the single-digit error [in the gven definition of pi]?” My answer: “Yes, both of them…”), but also mistakes that should never ever occur in a book on clean pogramming. Such as p. 302: the Employee apparently has a member function named isPayday.
Thanks for commenting. I too found some typos and errors in the book (but not more than is normal). I found an unoffical errata list at http://user.engineering.uiowa.edu/~wwalls/clean_code_errata/ and sent a mail with the three typos I found that weren’t already on the list. However, it doesn’t look like it is updated anymore.
As for the long function names, I don’t mind them. Understanding what it does from the name trumps the length of the name. But he also mentions in the book that a long and complicated name can be an indication that the function needs to be refactored.
Thanks, Henrik. The errata page has moved to:
Yeah, I agree!
PS: in case you want to point out that my posting contains typos [as well].. There’s a difference between an impulsively written post on a website (by a non-native English speaker, btw), and a book that is proof-read by a half dozen of people. 😉
I’ve read Clean Code and thought it was meant for people who code for big corporations. Where you have a lot of time and not a lot of requirements. Where you can spend years restructuring your object oriented architecture before you talk to your first customer. Where you can claim you’ve done your work because your program passes a set of tests. Where you hold weekly meetings to discuss a chapter of Clean Code.
But what inexperienced developers see as clean code is superficial code that does nothing. Real production code is ugly and battle-hardened. It’s the product of years of iteration, of solving customer edge cases, of working around framework bugs.
Before reading your artcile I did not imagine anyone would put this book in the same league as Code Complete or The Pragmatic Programmer.
Why in heaven would production code always be ugly because it is so-called battle-hardened and patched. You should always try to make sure the code is still clear, self-explanatory when possible; especially when the domain is complex and/or large.
Hell, even when coding on contests where speed is of essence I still want to code cleanly, so that I can debug faster (and hope to beat the likes of you who think that ugly is fine if the lifespan is only ten minutes… and then having to debug 20 minutes).
Totally agree. Most of the time, I’m under pressure, because the next deadline is coming closer in high speed – I don’t have time for unnecessary things and I especially don’t have time to dig through ugly code if everything changes once again (and things ALWAYS change). Writing clean code pays off – especially when you don’t have much time, because you can apply changes in a clean way without too much risk for breaking other things.
In my company are enough people who don’t share this oppinion, though. They are the ones who are extremely fast in delivering the first running version and later on the ones cursing and debugging more and more with each increment – and their stuff gets more and more buggy and their need for time to get the job done increaes rapidly…
Here it is an additional book reference in the same subject. I have read this first and then I have found Clean Code not so interesting.:
Code Craft by Pete Goodliffe
Thanks for the tip. I wasn’t aware of that one, but I’ll check it out.
I also saw on your blog that you’ve reviewed “Facts and Fallacies of Software Engineering”. That’s a great book! I wrote a review of it on Amazon a long time ago (now that I looked it up it turns out it was 12 years ago – time flies!).
Nice. What do you think about clean coder? Of course some parts of it obviuse, but sume is really usefull.
Thanks! I haven’t read it (yet), so I don’t know. There are other books higher on my list to read, but if I get around to reading it, I’ll post a review of that one too.
I love this kind of books, reading code is a big deal on any big project. The cleaner and easier it is to find functionality the better experience for the programmer and the less money spent working with death code/code analysis and duplicated code.
There is only one thing I don´t agree within your comments. I think Javadoc should be put almost everywhere… it is a tempting idea to use descriptive method names instead of good comments. For instance we know that it is not always possible, if you design by contract a single contract will have many different implementations and although the contract should be very well documented also the caveats of each implementation should be.
Even if your are the only programmer chances are that you will forget the implementation details and the intend of your method so a one liner comment might save you a lot of time… as long as it is a good/updated one liner.