The Refactoring Guide for PMs Tired of Endless Tech Discussions
Moving from tech discussions to value alignment
Clarifying Refactoring
“We need to refactor the code before implementing this feature.”
I’d be a millionaire if I’d get a dime whenever I heard this sentence. Yet, understanding why that was necessary and how to deal with it wasn’t always easy.
Despite having a technical background, dealing with refactoring from a product manager’s perspective often disturbed me. Here are some reasons:
Developers say it will take two days, and then it takes two weeks
We refactored a piece of code and broke something unrelated to it
Management continuously challenged why we had to do it
Intense debates between refactoring and adding product capabilities
Have you ever stumbled upon the above? Let me help you understand it. Here’s what we will cover in this post:
What’s refactoring, and why it matters?
Real-world examples of refactoring done right and done wrong
When to refactor
Refactoring techniques
Refactoring vs. rewriting
Let’s get into it.
What’s refactoring, and why it matters?
If you work with digital products, you probably heard the term refactoring several times, but what does it mean?
In short, refactoring means improving the quality of the code base while preserving its current functionalities. The result is more maintainable, scalable, and robust code.
You may wonder why software engineers don’t build it right from the beginning. That’s a genuine question, but let me give you two perspectives:
Build it right from day one: Getting your product into your customers’ hands will take a while. Yet, you may learn it’s not what they need, forcing you to adapt or throw it away. This approach requires a too-high upfront investment. Unavoidably, you create more waste than necessary.
Build to learn, then to scale: You prioritize learning over code quality. This approach helps you understand whether the solution is desirable and viable. When you realize it’s not, dropping it is simple as you didn’t invest much time. Yet, when you learn it’s worthwhile, it’s time to refactor and make it scalable.
From my experience, software engineers push for the first, while product managers push for the second. Meeting in between doesn’t work. What works is evaluating your current evidence:
How confident do customers want the feature?
Which evidence do you have customers will understand how to use?
How do you know which business value you will collect from it?
The more confident you are with the above, the more you can build it right from the beginning. Sadly, that’s seldom the case. This means that you will inevitably end up needing to refactor the code.
Let me bring it down to earth with the successful and failed situations I faced.
Real-world examples of refactoring done right and done wrong
I will start with a bitter failure I had to swallow because we can learn an important lesson from it.
Failed Refactoring
I worked for a digital marketplace, and customers complained that uploading new products took too long. The reason was simple:
Our image-processing algorithm was outdated
As the volume increased, processing pictures would take hours instead of seconds
Our shop didn’t present products without images
The problem was critical, and we had to act.
A senior software engineer asked me to let him refactor the code during the rest of the week. I agreed with him. As the week finished, he was confident, and we could put it live. We defined Monday of the upcoming week as the release date.
The refactoring went live on Monday at 7 am, and the image processing time became 150x faster. That was awesome. I couldn’t believe it. We were so happy I invited the software engineer for a delicious breakfast.
The marketplace director awaited us when we returned to the office at 08:37. His face was anything but friendly. “David, fix whatever you guys did. We’re missing 50K products in our shop.”
That was it. An unexpected effect of refactoring occurred. It caused a conflict with the shop importer, resulting in the removal of products from our catalog. Why did we get there?
Refactoring without having automated end-to-end tests
Low test coverage
Focus on making the code better without looking at the big picture.
It was painful, but it taught me a lot. Now, let’s look at a successful story.
Successful Refactoring
At the end of the month, we issued invoices to all partners. We had to change a few details to make it more transparent. When I brought that to the team, software engineers said they would not do it without refactoring it. The reason was simple: the code was complex, unscalable, and outdated.
I agreed with them on refactoring. The tech lead did the following to ensure success:
Confirm the tests are implemented
Understand the code in-depth before touching it
Search for dependencies and evaluate the impact
The team needed a whole week to refactor it. By the end of it, we learned:
95% of tests passed, but a few scenarios still failed
All dependencies remained working as expected
The code was reduced from 9000 lines to 6000
After evaluating the results, we invested another day to cover the remaining edge cases. That resulted in simpler and more maintainable code, which allowed us to add changes in a few days instead of weeks.
When to refactor
Knowing when to refactor is as crucial as doing the refactor itself. First, let’s agree on what a good refactor results:
The same functionalities working as well as before
Simplified code base
More maintainable application
No side effects with other parts of the product
The above is what you want to see whenever you finish the refactoring. Now, here’s what you need to have in place before you start refactoring:
Good test coverage
Code understanding
Clarity on dependencies
Functionalities understanding
As the above is present, refactoring will probably yield good results. But when should you refactor? Software engineers can always improve their code, which doesn’t mean they should always refactor. Knowing when to refactor is more like an art than science. When you observe the following, it’s time to consider a refactor:
Audience consistent growth
Software engineers complain the code is complex
Increasing code smell warnings
Onboarding new members takes considerable effort
Only one or another engineer can work on that part of the product
Frequent problems whenever the code evolves
Refactoring techniques
Once you decide to refactor, you can benefit from a few techniques. (This part of the post serves the best software engineers, but it wouldn’t hurt PMs to know it.)
Extract Methods: Some methods may become too long and hard to understand. Creating multiple shorter methods will increase readability and reusability.
Extract Class: As the above shows, classes can become extremely long and hard to understand; making them shorter will improve code readability and reusability.
Renaming: Readability is fundamental to helping software engineers evolve the code frictionlessly. Yet, it’s inevitable that classes, methods, and variables receive unclear names. You’d benefit from replacing them with clear names and following a standard naming convention.
Use Constants instead of Magic Numbers: Sometimes, the code receives numbers for conditionals. For example, “if score >= 7; pass = 1.” What does 7 mean here? Only with the context you’d understand. It’s better to define a constant, e.g., “PASS_SCORE = 7.” This improves readability and reduces bugs.
Simplify Conditionals: The more complex your conditionals become, the more trouble you may have. It’s better to simplify them so anyone can quickly grasp what’s expected.
Remove Unused Code: Eventually, some code will be there but not used anymore. It’s good to go; remove it.
Shift Methods: Sometimes, methods are positioned so that readability becomes hard. You can benefit from shifting them into a logically easier place to read.
The above represents a few examples of refactoring, which could help you with quick wins. Yet, you may wonder why your code is not refactorable. What should you do?
Refactoring vs. rewriting
When you choose to refactor your code, you understand it’s still useable, up-to-date, and relevant, but you need to make it simple to understand and more maintainable. Yet, sometimes, refactoring wouldn’t be the best choice. Reflect on the following:
What’s faster, refactoring or rewriting the code?
Is the programming language used still relevant, or did it become outdated?
Is your code understandable by everyone or only by the one who wrote it?
The more your answers are to the right, the more you’d benefit from rewriting the code. Now, let’s understand what rewriting means.
Rewriting means throwing away the current code version because it’s no longer maintainable or scalable. It implies redoing everything the previous code provided in a new way. This approach should be the last resort because it’s time-consuming and brings risks of unexpected side effects. Yet, you will inevitably end up rewriting the application for different reasons.
Conclusion
Code doesn’t need to be born perfect, but it does need to evolve according to the value it creates for your customers and business.
Refactoring is a mindful investment to keep your code base simple, scalable, and maintainable.
Refactoring requires preparation to avoid undesired side effects
Rewriting becomes an alternative when refactoring is more demanding than writing the code from scratch
Product managers and software engineers should have an open dialog about when to refactor and when not to
Whenever you’re ready, I can help you boost your career
Mastering Product Discovery: Cohort-based course for you to learn what most product people miss about product discovery. It’s hands-on and straight to the point. It had attendants from 30+ countries. Join us now to level up your product game.
Untrapping Product Teams Book: A book about hope for product folks. It gives you multiple perspectives on how to face reality and act today for a better tomorrow. Read by thousands of people in 70+ countries.
Anti-BS Product Management: Self-paced course to help drive value when almost everybody distracts you. You will learn the most common - and avoidable - mistakes made by product people and how to overcome them. You can expect lessons based on reality, not fantasy.
How to Craft a Product Strategy that Works: If you’re confused by what a product strategy is and how to craft one that works, this course helps you solve that. You will get all you need to create a sound strategy.
Product Discovery Done Right: How can you break free from the feature factory madness? Applying mindful product discovery will equip you to gradually move from outputs to outcomes. This self-paced course is dedicated to helping you learn what most product people miss out on.