I take a similar but somewhat orthogonal approach.
Most of the time, any major features that require refactoring are usually around the data model and its representation in code (the existing control flow and overall flow of a request through the system is generally fine).
I will build out what I believe the new data model should be, and then just work front-to-back, updating any references and refactoring the shared state and responsibility into the new data model, clearly separating out concerns and encapsulating responsibility.
This method has proved itself time and again, and I recommend it to anyone who needs to make large changes to and existing code base. That is, start with how the kernels of data, state, and responsibility should look, and everything grows from there.
Most of the time, any major features that require refactoring are usually around the data model and its representation in code (the existing control flow and overall flow of a request through the system is generally fine).
I will build out what I believe the new data model should be, and then just work front-to-back, updating any references and refactoring the shared state and responsibility into the new data model, clearly separating out concerns and encapsulating responsibility.
This method has proved itself time and again, and I recommend it to anyone who needs to make large changes to and existing code base. That is, start with how the kernels of data, state, and responsibility should look, and everything grows from there.