Clean Code & Code Complete
In college, I purchased and read the book Code Complete by Steve McConnell. As a novice programmer, it opened my eyes to good code — what it is, and how to write it. It is practical, comprehensive, and well-written. All developers should read it.
On the other hand, I have mixed feelings about Clean Code. It was published recently — 2008, compared to 1993 for the original edition of Code Complete. I had heard good things about the book and its author/editor, Robert C. Martin, so I decided to pick up a copy and read through it.
To book begins promisingly. After a nice foreword, the first chapter asks some well-known luminaries their ideas of “clean code”, defining the goals of good code. From there it moves on with the practical tips, beginning with chapters on naming, functions, and commenting.
As the book progressed, though, I felt it overall suffered from poor editing and cohesion. There are occasional grammar and spelling errors. The writing style is wildly inconsistent, due to many chapters apparently being written by different authors (despite Martin being credited as the sole author on the cover). The book’s organization as a whole is also messy; it generally progresses from low-level to high-level, as evidenced by the table of contents:
- Clean Code
- Meaningful Names
- Objects and Data Structures
- Error Handling
- Unit Tests
- Successive Refinement
- JUnit Internals
- Refactoring SerialDate
- Smells and Heuristics
- Appendix A: Concurrency II
- Appendix B: org.jfree.date.SerialDate
- Appendix C: Cross References of Heuristics
The first half of the book contains the standard guidelines that every good programmer should know. Later topics are less germane. I’m not convinced that concurrency warrants a chapter, much less two. (One is filed away in an appendix, but the author admits that it’s basically a second chapter.) Three separate chapters (14-16) are devoted to case studies; one (chapter 16) would have sufficed. Chapter 17 (“Smells and Heuristics”) is a nice reference, but it is neither comprehensive nor well-organized. (The categories are: Comments, Environment, Functions, General, Java, Names, and Tests.)
Compare this to the organization of Code Complete:
- Laying the Foundation
- Constant Considerations
- Quality Improvement
- Final Steps
- Software Craftsmanship
Altogether, Clean Code feels like a collection of blog posts cobbled together into a book.
I’m also not sure of the meaning behind “agile software” in the book’s subtitle. Most of the tips can be applied to any language and methodology. It has a chapter on unit testing, but so does Code Complete (in 1993!). The book stresses refactoring — rewriting and improving bit by bit — so perhaps that is what they meant.
The book also feels written for object-oriented languages, specifically Java. Rather than using pseudo-code, it assumes that you know Java. I guess Code Complete uses C and Pascal for its code examples, but Clean Code — with its long stretches of Java code, case studies on Java libraries, and sections on concurrency — definitely feels targeted to Java developers.
I don’t want to make it sound like the book is horrible. It’s not. I can’t argue against any of the principles laid out. It has a few guidelines that seem better represented than in Code Complete (such as “Functions Should Do One Thing”, “Hidden Temporal Couplings”, and “Functions Should Descend Only One Level of Abstraction”).
The writing also has its share of gems. Take the code smell G21 (“Understand the Algorithm”) — it reads, in part:
Lots of very funny code is written because people don’t take the time to understand the algorithm. […]
Before you consider yourself to be done with a function, make sure you understand how it works. It is not good enough that it passes all the tests. You must know that the solution is correct.
Often the best way to gain this knowledge and understanding is to refactor the function into something that is so clean and expressive that it is obvious how it works.
The short but critically important Chapter 12 (“Emergence”) discusses Kent Beck’s rules of Simple Design:
A system that is comprehensively tested and passes all of its tests all of the time is a testable system. That’s an obvious statement, but an important one. Systems that aren’t testable aren’t verifiable. Arguably, a system that cannot be verified should never be deployed.
Once we have tests, we are empowered to keep our code and classes clean. We do this by incrementally refactoring the code. For each few lines of code we add, we pause and reflect on the new design. Did we just degrade it? If so, we clean it up and run our tests to demonstrate that we haven’t broken anything.
Or how about the conclusion to Chapter 14?
It is not enough for code to work. Code that works is often badly broken. Programmers who satisfy themselves with merely working code are behaving unprofessionally. They may fear that they don’t have time to improve the structure and design of their code, but I disagree. Nothing has a more profound and long-term degrading effect upon a development project than bad code.
Wow. Manifestos like this need to be championed, and I worry that such important advice on craftsmanship and self-criticism will be overlooked among the code examples and other details.
So, is it worth reading Clean Code? Yes. If you are new to programming or haven’t read Code Complete, I would strongly recommend reading that book first. Clean Code offers good advice and practices, is a bit more modern, and tries to approach it from an agile methodology angle, but it is hampered by its poor editing and organization. A new edition, with tighter writing and a refocused approach, would be more effective.
I see Clean Code as more of a supplement, or a refresher. For me, Code Complete is the bible; Clean Code is a handbook.