"Honey, what have you done? My father wants to kill you!”
😨
I never knew my tendency to refactor stuff would get me in so much trouble…
Let’s back up a little.
Yes, I promise this relates to the software world.
Back in February, my wife's parents invited us to their home for 2 weeks. We had a 3-month-old baby (our first), and we appreciated the invitation.
The help was amazing - we finally had some free time, slept well, and ate great food!
Near the end, I decided I wanted to pay back the kindness. On a Saturday morning, they all went out, and I had a great idea.
The house has a huge yard, which was a complete mess:
Piles of garbage
Fallen leaves everywhere
Abandoned tools in random places
Old and rusty buckets getting in the way
Her mom always complained about how messy it was, so I thought my idea was GENIUS!
I cleaned up everything - I organized the tools on the shelves, collected all the fallen leaves, and threw away the garbage and the old buckets. The result was something like 5 huge bags full of trash!
I took a shower and went for what I thought was a very well-deserved nap.
Imagine my surprise, when I woke up to my wife saying: “Honey, what did do? My father wants to kill you!”
You get where this is going, right?
Turns out that although I cleaned up some real garbage, I also threw away
the compost corner my father-in-law started a few weeks ago.
In addition, the leaky buckets were placed under strategic places where the gutters overflowed during heavy rains, and they distributed the water in a better way.
And worst of all, my mother-in-law was very happy, and kept saying: “Look what a great job Anton did! You should learn from him!”
🤦♂️🤦♂️🤦♂️🤦♂️🤦♂️
And one more:
🤦♂️
But enough about my in-laws, let’s go back to tech.
Why do developers always want to refactor?
How often did you hear from someone in your team: “This repo is in terrible shape, we must refactor it!”.
I’m working at a 10-year-old startup, so there is no shortage of old repositories and obsolete code lying around.
I agreed with most complaints, and that’s what I usually did: if we needed to do substantial work in a certain place, I factored in ‘tidying it up’ in the estimation.
Until one day, the ‘this-repo-is-in-terrible-shape-and-I-can’t-understand-anything’ complaint was directed at a codebase that I wrote myself 2 years ago! It was covered with UnitTests, well documented, and still highly used!
I was confused. Was I a worse programmer than I thought? After consulting with some people from other teams, and asking them to go over that code, I concluded that it’s not my fault (this time).
Since the dawn of time, developers always wanted to re-write things.
Joel Spolsky wrote in his great 25-year-old article:
Programmers always want to throw away the code and start over - as they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a fundamental law of programming:
It’s harder to read code than to write it.
This is why code reuse is so hard. This is why everybody on your team has a different function they like to use for splitting strings into arrays of strings. They write their own function because it’s easier and more fun than figuring out how the old function works.
You can ask almost any programmer today about the code they are working on. “It’s a big hairy mess,” they will tell you. “I’d like nothing better than to throw it out and start over.”
This was written in 2000(!), and I find it fascinating it’s still true. It can cause an endless cycle - if a code I wrote mere 2 years ago is already considered ‘legacy’, who will guarantee that the new code will be better?
It’s important to remember that when you start from scratch there is absolutely no reason to believe that you are going to do a better job than you did the first time. You’re just going to make most of the old mistakes again, and introduce some new problems that weren’t in the original version.
The concept is best explained by the famous illustration by Manu Cornet (there are many more great comics on his website!):
Old code is the best code
Jumping back to my father-in-law’s backyard story (I swear, it’s real. Since then we made up, but this stain will last a while…) - when you try to rewrite a codebase you don’t fully understand, you will fail.
During lunch a few weeks ago, someone asked one of the developers in my team how long it would take to write one of our internal-facing systems from scratch.
He looked at me and said: "Something like 3 months, right Anton?"
And I replied: "Closer to 6. And then 3 more years to add all the edge cases".
The longer the code exists - the more stable it is. When I started leading my team 2.5 years ago, I was given a legacy system to support, that nobody really knew. So far, it had maybe 2 small problems due to external API changes, and is just working flawlessly…
Code is like wine - it ages well.
Vadim Kravchenko wrote a great article about it:
Why should you consider aging your code? Because the longer your code has been around, survived different cataclysms (read: business pivots), and evolved, the more robust it is. The team that has built it before you had time to debug, to optimize, to improve — the code has accumulated years worth of bugfixes that are in places you cant even imagine.
The kinks have been worked out, and what you're left with is a mature, stable system that can handle whatever comes its way.
Finding the balance
I'm not saying that code should be kept forever. Requirements change, and new technologies emerge.
My point is that developers should be much more careful with how they define ‘legacy’, and how trigger-happy they are with refactoring.
Your role as a manager is to help the team find the balance - represent the developers, fight for the time to refactor when you believe you need it, but also represent the business side, and push back if you believe a refactor is not critical right now.
2 things I advice you to do before starting a refactor:
Think about the future. Are there big features planned in that codebase in the near future? If not - wait for them before you do anything, they might never come.
Make a TRUE effort to understand the old code. Let a developer spend a few days trying to understand the existing code. I’m surprised how often 6-8 weeks long refactor projects are started without even spending a day to understand what you are trying to replace!
If the developer feels more confident after a few days, maybe a huge refactor is not that urgent.
The next time you consider refactoring a working codebase - remember my father-in-law...
What I enjoyed reading this week
5 Tactics to grow your product in
. An amazing curation by , the best I’ve read in a LONG time!10 Interview Techniques From the World’s Best Interviewers in
. I found this one Jaryd’s article, SUPER insightful lessons!Why everything is becoming a game in
. The most thoughtful take on gamification I’ve read. publishes only once a month, but he really makes you think.
This is a very important thing to learn. We shouldn't throw away old wisodm because it's hard to understand. That's exactly the learning that is most valuable to keep!
One thing I still wonder after reading this article though, is how can we tell the difference between code I don't understand and code that should be improved?
Thanks for the thought provoking blog today!
Very funny story, Anton with a great lesson attached. Be careful to not break what isn't broken! Refactoring certainly isn't free. As much as better code would be great, sometimes the "right" thing is far more effort and risk than just letting it do its thing