I'm a Software Engineer with 10+ Years of Experience. I believe quality leads to velocity.
Clean Code is a Lie and Nobody Writes it.
I have a love-hate relationship with the famous book Clean Code by Uncle Bob. For years now, I have taught a course on it for professional software engineers. I have read the book itself a dozen times, and each time I have learned something new. That being said, I find almost half of the contents to be wrong. While I hope to cover many of the lessons I have learned, from that book, others, my mentors, and my experiences, I would like to start with what Clean Code actually is, or more accurately, what it is not.
The issue with Clean Code as a goal is that it is entirely subjective. If you ask 7 highly experienced, noteworthy, software engineers to define clean code, you would end up with 7 very different definitions. To prove my point Uncle Bob does exactly this in his first chapter (7 including himself).
Dirty Code on the other hand is quite objective. I can certainly write a piece of code, of which, every single engineer I show would agree it's a mess.
This means that there is a spectrum, from Dirty Code to Clean Code, where one side is objective and the other is not. The following chart illustrates this succinctly.
In the chart, several code samples are rated by a group of engineers. Each sample is then sorted by its average rating. Error bands are used to show agreement on a given rating. As you can see, as the average rating increases, so does the deviation in ratings.
If Clean Code is subjective, what other, realistic, goal can we have for the code we write? How about writing code that is simply less dirty?
Before we can define, in clear terms, what dirtyness within code is, we should first agree to the prioritization of what the purpose of code actually is. In no specific order I am going to share some of the potential priorities you can have regarding code.
These are many of the aspects people discuss when they try to define Clean Code. Consider how you would order these.
I lied earlier when I said they were in no specific order, I prioritize these things in the exact reverse order they are shown. If code is readable, any engineer can understand it, which means they can make the other aspects happen with ease. In fact, "the ratio of time spent reading old code is well over 10:1. We are constantly reading old code as part of the effort to write new code." (Clean Code, Robert C. Martin). If code is easy to understand, it is easy to test, change, and run. If it is those things than it is easy to extend, fix, deploy, and improve. And finally, if you can put it in front of actual customers, you can add resiliency and efficiency where it provenly matters. So, there are four tiers of priorities:
Each tier makes the next easy to accomplish. Given this, we can simplify dirty code as code, which is difficult to read.
What is readable to one person isn't necessarily readable by the next. Experience levels vary. Comfort with the different paradigms of software, language features, libraries, compilers, operating systems, etc., all vary too. And perhaps most importantly, there is never a perfectly shared common culture and vocabulary between reader and author. All we can aspire to do is maximize readability for the most people possible.
There is a reason a lot more people have read The Cat in The Hat By Dr. Suess than Ulysses by James Joyce. It is consumable by a wider audience. It's more readable. Certainly, we can argue which is a greater masterpiece but we cannot argue which is harder to read.
I contend, that an idiot makes a much better code reviewer than a genius (I also contend that this is why I am pretty decent at code reviews). When an idiot comes across clever, surprising, side-effect filled, unexpressive code, they struggle with it, so they have little trouble pointing these things out. When a genius reads these things they are barely slowed down. Though the idiot may not always have an idea how to fix the problem, identifying there exists a problem is the critical first step.
So there are drawbacks to being either an idiot or a genius. Fortunately, no matter where you fit along that scale there is only a single thing to do: Constantly improve yourself, and the code you write.
There is a ton of media (books, blogs, videos, etc.) which outline how to write better code. They do this by outlining rules to follow. The problem with these rules is they are often in conflict with one another. Many write this off as meaning they are useless, or simply opinions that can be ignored. It's true, in software every rule likely has an exception, but just because they shouldn't be followed always, doesn't mean you shouldn't error on the side of following them as often as possible.
But there are so many rules, where do you start? My Advice is as follows:
Finally, what about rules which conflict with one another? This will happen, it is up to you, as the craftsperson, to take into context the problem you're solving and make a choice on which rule takes precedent.
I have slowly built up a set of rules which I follow when I write code. I will follow this article with ones outlining each. I will begin with the simpler, higher priority, and more useable ones. I will also write about anti-rules which are often promoted but will cause you more pain than good. If you follow all of my rules your code won't be clean, but I guarantee it will be a little less dirty.