Over the course of the years, I’ve been a big promoter of the Clean Code “philosophy” as a result of its amazing influence on my daily work. As I still believe in this philosophy and promote its benefits, I came to realize that, as everything we interact with, it can also have a dark side if used mechanically or without considering the bigger context. What I want to highlight in this article is not a set of practices but more of an approach for the way we craft our code.
The helpful servant
When I first saw this picture I found myself feeling uncomfortable because of the fear of discovering after which door I might be standing. That was the exact moment I got triggered and became interested in respect of two things: first, ways of positioning myself on the good side of the story and second why it was so important to take care of my code. The more I was looking into it the more I was feeling anxious about the code review I might receive.
After years of practice, I came to acknowledge the importance of two things: on one hand, the awareness of clean code and best practices and on the other hand the importance of going beyond, being aware of these principles and actually applying them in my daily work.
When it comes to details we, as devs, tend to focus more on the logic of things, how they should work and that they actually work as expected, and less on how, over time, this code might extend and transform. Basically, we don’t always think about the fact that we might find ourselves in the situation to use or extend that code in the future, so we need it in good shape.
When bringing the subject of clean code to light, I often hear some common objections about how taking care of our code is not that important:
- My code will never change
Except for the case where that piece of code will never see the light of the day or of the production environment, most probably your code will change, “Software cannot stay as it is because the requirements that defined the software have a firm attribute called CHANGE”.
It doesn’t matter if its requirements change, if new features are added or if it is mandatory to upgrade the technology stack, someone will have to do that change and look over that code again.
- I don’t have time for Clean Code
Let me put it this way, the ratio of time spent reading versus writing code is 10 to 1, therefore making code easy to read and extend makes it easy to write.
- I’ll clean up later
Later never comes and what we don’t do in its time we never get to do. It might sound like a cliché but it couldn’t be truer. Postponing “cleaning the code” to later today to postponing it to later in the sprint or in a technical debt user story in the future might seem like an easy way to efficiency. In reality, by repeating this pattern, we get to the point where we lose context, the code becomes a burden and spending time on refactoring 3 months later it will be painful. Trust me, it is physically painful.
- My code is too complex for these details
Being the only one that understands a certain piece of code might be good for the ego but is bad for the reputation and worse for the team. If those details make the difference and speed up the process of developing a valuable product they deserve some extent of your time.
- I’m too smart to mind with this
Have you ever had to struggle with the code that someone left in a very bad condition? In this situation, have you ever said: “Oh, this person was too smart to take care of this piece of code, I wish I’ll be like this person when I grow up”? I really hope you didn’t. The point is we have to write that code as we care. It all comes down to one word, RESPONSIBILITY.
Let’s put it this way if you go to your doctor for surgery and the doctor says that he studied too many years and that he is way too smart or busy to wash his hands and change his clothes how would you feel about his decision? If you are thinking that the comparison is trivial and that we, by the nature of our job, are not dealing with people’s lives, as doctors do, think about that again. At the speed technology is evolving these days, it touches a big number of areas from medical tech to self-driven cars and beyond, the importance and attention you put into your code might influence someone’s life at some point, something like the butterfly effect — small neglected pieces of code can have big consequences in the future.
“The way we do anything is the way we do everything”
In your career, you will most probably work more on already started projects than new ones so you will have to deal with someone else’s code or your own “past code”. If you come to see a piece of code that is not ok you can’t keep ignoring it. In every file/ module you touch, if you find something that could be improved do it, even if it’s just the naming of a variable or extracting a method. Little things like this make the difference between a professional and a nonprofessional.
If you, as it was my case, are not sure where do you stand and how much more practices you have to review and include in your day to day work in order to gain some confidence I’ll leave at the bottom of this article some references to start from.
The dangerous lead
When you are working in a stable environment for a while, where healthy decisions regarding clean code were made, it is easy to love, promote and continue following the same approaches that helped you get the best results. But what do you do when the best practices that should give you a hand actually complicate everything because they are misunderstood? What do you do when everything is GENERIC, and you have an abstraction over another abstraction? Well.. you think about a plan on how to create “realistic” refactoring.
By realistic refactoring, I mean that instead of opening the “Bible of best practices & clean code” and start typing like there is no tomorrow you’d better take a look at the context of the application. While some clean code rules can be easily controlled with a set of strict lint rules, naming conventions, a file structure predefined, etc, some are more sensitive and need special attention. If you are working on an application that is at a mature development level chances are that when you start a refactoring process you can notice some patterns in terms of business so it might get easier to make some decisions on what should be generic and what can be specific.
When trying to puzzle out some code the best you can do is look at best practices on one side, consider your application context on the other side and in the end sum up everything and take decisions assuming some responsibility. As I am continuously looking for ways to improve our code, I came to the conclusion that it is pretty hard to make a perfect decision but you can build over your experience and discuss approaches. Keeping your code’s hygiene is a team effort, refactoring is a team effort, decision making is based on the team’s experience.
In the end …
Being at the beginning of your career the best you can do is respect best practices and constantly request code reviews from someone more experienced. In time, while some code hygiene practices are going to become a part of your professional gut feeling on other occasions you might want to ask this question “How does this suit the needs of my system?”. I encourage you to read this piece on “The wrong abstraction” as an argument, I couldn’t have said it better. :)
Maybe it is just my athlete side talking, but I really think that we should give more importance to our work and try to contribute to our craft the best we can. I am against creating a soulless work-life composed of 9to17s we don’t ever remember or take pride in.
Clean code is not the ultimate objective in our programmer life, it is more of a way of untangling the ever-changing complexity of our system. I’m not saying that we shouldn’t use it, I couldn’t actually since I still have my “Clean code promoter” badge on, I’m just advising you to use it wisely, take responsibility for every decision and always look at the bigger picture before you start anything.
- Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin
- The Clean Coder by Robert C. Martin
- A Philosophy of Software Design by John Ousterhout
- Building Maintainable Software, C# Edition: Ten Guidelines for Future-Proof Code by Joost Visser
- Working Effectively with Legacy Code by Michael Feathers
- Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series) by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides, Grady Booch
- The Pragmatic Programmer: From Journeyman to Master 1st Edition by Andrew Hunt, David Thomas
- Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin