Refactoring should not be a negotiation
I've observed and worked in a few teams, usually in large organisations, where refactoring and addressing technical debt was always a negotiation. It was regularly discussed with management, but invariably put to the side in favour of delivering more features.
This invariably led to delays in delivery due to the poor quality of the project.
Once I got into a position where I could have more influence, I made an agreement with my teams: If you see an opportunity to make something better, take it. Obviously there were some caveats around this, like don't unravel the sweater, but the intent was clear:
We trust you, so you will be given the time and space to refactor and improve continuously.
It wasn’t until recently that I found out this had a name, when I read an article by Martin Fowler on Opportunistic Refactoring.
“Some people object to such refactoring as taking time away from working on a valuable feature. But the whole point of refactoring is that it makes the code base easier to work with, thus allowing the team to add value more quickly. If you don't spend time on taking your opportunities to refactor, then the code base gradually degrades and you're faced with slower progress and difficult conversations with sponsors about refactoring iterations.”
So what can you do if you’re in a similar position? All of the problems I’ve seen in engineering teams typically come down to 1 thing:
A lack of trust.
Both a lack of trust in people, and a lack of trust in the system.
In order to build trust in you as an individual, you need to start small.
Start by refactoring one function, one class, or one component that’s related to what you’re supposed to be working on. Show your team and the business that you can still deliver valuable working software quickly, while still having the time to make things better.
In order to build trust in your system, you need tests.
Tests are imperative in any good software, but if you are working on a system that’s resistant to change and/or has no working tests, adding tests will be vital in building trust in both you and your system as you work to refactor and improve things.
From there you can use more advanced techniques like strangling the fig, and branching by abstraction, to undertake more substantial refactoring or replatforming.
It won't happen overnight, but over time you will start seeing the benefits of seeing refactoring as an "always on" activity.
Better quality, faster delivery times, and most importantly happier teams.
Are you working in a low-trust environment and struggling to get work done?
What have you done to pushback against or work around management delivery goals to improve things?