People often talk in the abstract about refactoring while writing code. But doesn’t that mean you just have a huge pull request with lots of unrelated changes muddled together? Or worse, several separate pull requests that conflict with each other?
It doesn’t have to be like that.
There’s an exercise I’ve used with great success which trains you to write code in the right order. It’s called Baby Steps. You start a 2 minute timer and start making your change whatever way seems sensible. When the timer goes off, if you have compiling code with green tests you may commit, otherwise revert. After all, you’re only losing 2 minutes of work. The idea is not to get faster at pressing the keys the next time around, it’s to learn what was blocking the change you tried to make, and focus in on that next iteration. You might need to keep note of why you’re doing various tasks and how they fit into the bigger picture – this methodology was formalized by the Mikado method.
When doing this, you’ll often find you’ve written a whole sequence of changes which are pure refactors*. You could pull request and merge them without actually changing the behavior of the application, but they change the shape of the code to make space for the feature/bugfix you’re currently working on. By the end of this process, your feature/bugfix can be a simple single-line fix. You should also find you hit the timer less often as you get used to identifying smaller problems mid-way through and resetting early. I’m not going to say you should always work to a 2 minute timer, but I’d certainly advocate the overall style of development. Taking turns at driving when the timer goes off works great in a pair to keep you both engaged. Note that this doesn’t replace other methodologies. If it’s a big change, spike it. Still use TDD, BDD or whatever you’re using this week to drive your development.
To summarize, use pure refactors* first to make space for your the changes you’re working on. Then make your behavior changes separately. Baby Steps is a great way to practice doing this that works on real code.
Refactoring an API? Try Expand, Migrate, Contract refactoring.