Reflections on Clean Code
Lessons Learned from a “Must Read” of Software Engineering
One of the most important elements of a software engineer’s personal development is reading. In a field so vast, and so varied, constant reading is important both for building foundational knowledge and exploring branch knowledge. And as in any profession where the written word plays a large role, software has its “must read” books. One of those, is Clean Code, by Robert C. Martin. In fact, when I ran a Google search for “top software engineering books,” four out of the top five results recommended Clean Code and the fifth recommended another of Martin’s books, Agile Software Development, Principles, Patterns, and Practices. If a book’s importance can be judged by the number of times it is recommended, then Clean Code is a book worthy of conversation. To that end, I’d like to share a few reflections on my own reading of Clean Code and what the book means to the craft of software development.
In many ways, Clean Code is structured like an owner’s manual for writing good code. It describes best practices and exhorts professional coders to use them. Simultaneously, it picks apart poor practices and admonishes those who fail to recognize them. Clean Code is an extremely opinionated book (no doubt like its author); however, the opinions appear to be based on experience. Martin and his team are open about their own failures over long careers and what they learned from them. Years of reading (and sometimes writing) bad code seem to have made the author intent on helping other developers veer clear of danger. Practiced together, the hundreds of recommendations from the book — large and small — no doubt produce excellent code; however, fully absorbing and adopting so many ideas at one time is impractical. Such lessons must, to some extent, be learned the hard way — by suffering through bad code enough to want to make it better.
Given Clean Code’s length and the granularity of its recommendations (literally down to the level of line spacing), I won’t attempt to summarize its content. For that, I recommend that you read the book yourself. Rather than see Clean Code as a collection of unbreakable commandments to be seared in the brain of every coder, I prefer to see it as a spiritual guide that sets the tone not just for how to write good code but for why to write good code. My reading of the book aimed then not for rote memorization of rules (though many of them do stick with me), but for the absorption of a crafter’s mentality that encompasses certain inviolable values.
Rather than see Clean Code as a collection of unbreakable commandments to be seared in the brain of every coder, I prefer to see it as a spiritual guide that sets the tone not just for how to write good code but for why to write good code.
No doubt every reader of Clean Code will take away from it their own lessons; however, if I were to boil it down to three core concepts, I would do so as follows.
- Craftsmanship Matters: Rarely does a coder have the freedom to sit with a piece of code until it is truly perfect. In fact, such a feat as writing “perfect code” may not even be achievable. However, writing the best code possible should be a software crafter’s top priority. At times, this will mean pushing back against deadlines, client demands, management demands, fatigue, and all other manner of competing forces. It’s true that business conditions often set boundaries on what is “possible,” but a coder always has at least some control over the quality of what they write. Clean Code repeatedly hits on the point that just because code “works” doesn’t mean it’s “done.” But if a coder’s job is to produce a product that solves some problem, why should it matter how it solves the problem? In short, because everyone benefits in the long run — client, user, management, company, and coder. Code that is messy, rushed, “good enough”, etc., is code with an eye on short-term returns. To produce long-term value — the kind that persists through years of updates, bug-fixes, and feature addition — requires attention to detail. This is what writing clean code is all about — it means approaching code with the mindset that high-quality input (thoughtful, maintainable, flexible code) results in high-quality output (long-term business payoffs).
- Extra Effort Today Saves Pain Tomorrow: The point about high-quality craftsmanship producing greater long-term returns is worth emphasizing. All of us have experienced the disappointment that comes with using a low-quality product. Think of the shirt you buy that frays at the edges after a few runs through the wash, or the cheap plastic toy that breaks mere moments after your child takes it out of the box. Poorly crafted code is no different — it frays at the edges much faster than you might think. Compare this to something of yours that you treasure for its quality. For example, I had a pair of shoes that I wore almost daily for over a decade before they finally wore out. They were a bit more expensive than other shoes but their quality was undeniable and I saved money in the long run. And what did I do when the time finally came to throw those shoes out? I went and bought an identical pair because I knew that they would last me another decade. In code, the same principle applies. High-quality input not only produces longer-lasting output, but it also saves money and builds customer loyalty. Meticulously refactoring and testing your code may take longer in the beginning but the savings in technical debt and maintainability are well worth the extra effort.
- Your Code is Not Your Own: It’s important to take pride in your own work; however, it’s equally important to recognize that the code you write is not your own. This may seem a bit of a paradox — after all, writing clean code requires that you have a stake in its quality — but on closer examination the reason why good code is not really yours becomes clear. Most of the code that we write is intended for consumption by others — either by your teammates, your customers, or by your future self. If the code is not clean, readable, and easy to understand, then it’s not particularly useful. What happens when some future project maintainer (even if that person is you) can’t understand why you’ve written something the way you have? They will no doubt have to spend precious time and mental energy deciphering the puzzle you have left for them, and worse yet, they may very well fail to understand its intricacies. Imagine, for example, if an author wrote a book that conformed to some unique and bizarre set of grammar, spelling, and structure preferences. Would anyone else understand that book? Would anyone want to read it? Likely not. Code is no different. Write as though your code is a common good, to be read, understood, and maintained by many different people, and you will end up with a far superior end-product.
Clean code requires a constant attention to detail and a willingness to acknowledge that what you wrote yesterday can still be improved today.
What is Clean Code?
If writing clean code is so important, then what exactly is clean code? Martin and his colleagues have written an entire book to answer this question, but a few themes can be extracted. For me, these are the true takeaways from Clean Code — themes that one can refer back to, consciously or otherwise, while writing code and endeavoring to make it as high-quality as possible. Everyone will have their own list of what makes for clean code, and indeed, Clean Code begins with a collection of definitions given by various software luminaries, but in my mind, clean code includes the following attributes:
- Clean code is simple. Perhaps not simple in algorithmic or system-level complexity, but certainly simple in implementation. Overly-clever tricks, hacks, and sleights of programmatic hand are fun only to the author and diminish the code’s long-term value. The same goes for long-winded code that takes too long to get to the point.
- Clean code is readable. If the naming conventions, spacing, structure, and flow used in a program are not designed with the reader in mind, then that reader will almost certainly fail to understand the original author’s intent. Conventions about how to write readable code may seem dogmatic or lacking in expressiveness but they help to make code communal rather than arcane.
- Clean code is considerate. Code that does not do its best to inform future readers is code that does not respect their time. Good code should be written in a way that both assumes future consumers are intelligent, thoughtful professionals (like you), and still goes out of its way to help them. After all, nobody likes to waste time trying to figure out why something was written the way it was and how it’s supposed to work.
- Clean code is tested. No one writes perfect, bug-free code on the first try. And even if they did, there is no guarantee that it won’t break later. Writing clean code means writing tested code. That way, future users can be confident that they are interacting with something that works. And when they make changes, they will have a ready-made test suite to confirm that nothing broke.
- Clean code is practiced. Writing clean code requires good muscle memory, just as does playing an instrument, kicking a ball, or frying an egg. The best way to learn to write clean code, and more importantly, retain the skill, is to do it all the time. This means that when you’re at home working on a personal project, you do it with clean code — even when no one else will ever see it.
- Clean code is relentlessly refactored. Even the most consummate of professionals doesn’t get things perfect on the first try. Clean code should be in a constant state of refactoring. And with a good test suite to back your code up, you can refactor it as much as you like and never worry about breakage.
- Clean code is SOLID. Good code is as much about good design as it is about cleanliness. Following the SOLID principles is one way to ensure that your code is flexible, maintainable, and long-lasting.
The list of attributes for what makes “clean code” could no doubt go on, but the above is a good place to start. As simple as this list seems, putting it into practice isn’t easy. It requires a constant attention to detail and a willingness to acknowledge that what you wrote yesterday can still be improved today — even if it worked just fine before.
Of the many books that software engineers are told are “must reads,” Clean Code by Robert C. Martin has a well-deserved place on the list. Although the book contains a plethora of useful rules and best practices, it is perhaps more useful for the mentality it imbues in its readers. One can interpret this mentality in many ways but a useful starting point is to say that craftsmanship matters, effort today saves pain tomorrow, and code is never really your own. As a concept, clean code has many attributes, but at a minimum it is: simple; readable; considerate; tested; practiced; relentlessly refactored; and, SOLID.
If you haven’t ready Clean Code, I highly encourage you to add it to your list. It’s not perfect, and it’s prescriptive nature can be jarring at times; however, a close read will leave you with a useful mentality with which to produce effective, long-lasting, and valuable code.