I was re-reading this last week this Joel Spolsky (co-founder of Trello and Stack Overflow) blog post Things You Should Never Do and wanted to write little about it! In the post he writes about one big mistake engineers often do: Re-write everything from scratch. We all have been in a point that we either though
“agh, this code is a mess I should rewrite it all over”
or
“This system is very old and full of tech debts, we should create a new Plaftorm✨ and make it extensible ✨
✨ yes fancy words we often hear and speak to sell ideas hehe
But why do we think this? When should we really re-write something?
Why we re-write software? Or want to re-write
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. First of all, you probably don’t even have the same programming team that worked on version one, so you don’t actually have “more experience”. You’re just going to make most of the old mistakes again, and introduce some new problems that weren’t in the original version.
Joel Spolsky - Things You Should Never Do
Code many times its hard to understand
Joel in the blog post also mentions this:
Code its harder to read than to write it.
So we see a code, that lacks documentation, has multiple interactions and no schema/types declared and you have to spend 5-10 minutes just to understand the intention of the function. Sometimes its clever code, but also many times its just because its hard and we have our personal way of approaching problems.
Our way. As engineers, problem solvers, each one of us have a distinct way of thinking and approaching a problem. This way, when we face someone’s code, many times it doesn’t perfectly match what we were expecting and this makes us think that its confusing the code or its too complicated. It can be to bad implementation or too much responsibility in a single place, yet can be our brain trying to understand what the person who created the code was thinkin when writing.
We think we could do it better and the self-challenge
So you spend the time but, writing code its easier than reading, so we have the brilliant idea of refactoring to be “better”. Not document, not improve partially but create a new enhanced version 😊.
You know, we like to challenge ourselves, think of solutions, try to optimize code and make it faster. This way sometimes the code isn’t that clear, not documented, you think you can do better and this triggers you to prove yourself that you can refactor the whole flow and make it better. You might make it better or just another version of a solution to solve the same problem that was already solved.
Output rather than outcome
One thing that also happens a lot its that many times we enter a phase in a team of output > outcome. Ship, we need to ship a lot, tight deadlines and we start to loose track, we don’t write documentation, have no time to think of good abstractions and create a big ball of ducktape and nested code. Then we winddown, the roadmap its good and you lookback there is a big system with lots of decisions that we don’t even remember why that seems that can collapse at any moment. So we enter the premature fase of ✨Tech Debt.
This unfortunately will happen with most people and we will need to face this restructuring in the future
Why not refactor?
When everything points to refactor why not refactor it? Many times we will need and its something we can prove, either though stacking tech debt in the team or just overall moral about how things are just hard to maintain and scale. And the last two its directly linked with the team capacity of delivering business value. And when its not clear if we should refactor, why we shouldn’t?
Will your code be better or easier to understand?
When we refactor, we usually think the code will be better, simpler and sometimes “less legacy”. This after you finish might hold true but only for you… since you coded, you thought about the idea and implement it, all the ideas are in your mind. This false sense of Job Done will lead some other engineer to the same feeling you have of “I need to make this better”.
So instead of refactoring try improving it, specially with docs. Is there a sequence diagram of the flow? Does the functions have DocStrings? The naming seems good and cohesive? And from there try other things such as breaking the code into smaller atomic functions, this will lead to easier unit testing and this also helps to understand and reason about the code!
No apparent business value
This is something we will struggle, either being right about the refactoring or totally wrong. Spending time on intangibles - tasks that doesn’t have a clear correlation with business metrics, such as code patterns refactor, refactoring tests to be clear to read, documenting (many times considered intangible 🤷) - usually is hard to justify and prioritize within the team, so justifying to refactor a code or system without a good selling point for the business is usually a no go for leadership. Specially if your company doesn’t sell technology, but uses it do deliver other products. Focus on the value!
Refactor less, document more
Be cautious about refactoring, don’t let your crafty engineer within refactor the whole codebase just because you read a Medium post about GraphQL. Also this empathy work to understand how the system was done, the context in which was written, maybe tight timeline high pressure with no devs. This will make we see more ways of being efficient and also improve the work, many things we build in life we don’t “reinvent wheels” or create things differently just because we could do better, focus in what value you wanna bring. Refactor less, document more!