Refactoring: How Far Should I Go?

Refactoring is an essential practice for teams developing solid software and continually evolving the design to meet new customer needs. From the home page managed by Martin Fowler, who wrote the original book on refactoring, it says:

“Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.”

On a project that is well tended in terms of its design and structure the act of refactoring can be elegant and liberating. It will allow teams to continually inspect and adapt their understanding of the code and the customer’s need as they gather feedback on the software.

On a legacy system the act of refactoring can seem overwhelming. Although the refactoring craft revolves around the mindset that continually making small incremental improvements will lead to overall improvement in the design figuring out where to start and stop in a legacy system is unclear. This blog entry is for teams who are unclear on where to begin refactoring and how much refactoring is sufficient day to day.

Where to Start Refactoring?

On all teams that I have worked with either as a team member or coach this question starts with the answer:

When the feature you are working on exposes the need to refactor

The problem is that this does not give a full answer with context and understanding for the particular project we are discussing. I like to answer the following questions before starting to refactor:

  • Does this change directly affect the feature I am working on?
  • Would the change add clarity for the feature implementation?
  • Will the change provide automated tests where there currently are none?
  • At first glance does the refactoring look like a large endeavor involving significant portions of the system components?

For the first 3 questions if the answer is “yes” then I am leaning towards starting a refactoring of the code. The only caveat is the answer to the last question. If the answer to this question is “yes” then I will use my experience with the system help me generate a gut feeling about the size of this refactoring compared to our initial cost estimate of the feature implementation. If the size of the refactoring is significantly larger than the cost estimate given to the Product Owner / Customer then I may decide to bring the refactoring up to the team for discussion. As we teach in the Certified ScrumMaster course:

The Product Backlog estimate is a mutually agreed budget. If the team is going to exceed the budget, it needs to escalate the decision. Otherwise, the team introduces scope creep.

When to Stop Refactoring?

Using the word “stop” is misleading since it means we just decide to quit at some point in time without regard for the situation. I would not suggest this at all. Instead the following conditions are what I use to figure out when I have finished a refactoring:

  • Am I refactoring code structures that are not directly affected by the current feature?
  • Are there any more code structures that are directly affected by the current feature I am working on that have not been refactoring sufficiently?
  • If the refactoring is blowing our mutually agreed upon budget for this feature with the Customer then I should bring this up to the team to discuss further progress
  • If we decide as a team that the refactoring can be absorbed into the current iteration without affecting delivery on our original iteration commitments then continue to refactor
  • If the refactoring cannot be absorbed into the current iteration without affecting delivery on our original iteration commitments then we must bring it up to the Customer to discuss how to proceed

If the situation leads us to bringing up the refactoring to our Customer then the options for are to:

  • Simplify the original feature - the team could bring a suggested simplification to the customer
  • Remove the feature from the current iteration commitments
  • Remove one of the other features from the current iteration commitments

Wrap Up

Starting a refactoring should be identified in the course of implementing a piece of business value prioritized by the Customer. We should gauge the size of the refactoring against the cost estimate given to the Customer. Wrapping up a refactoring should not be done without regard for the quality of our implementation going forward. The result of a refactoring should be improved code structure while preserving existing functional behavior. Use the questions, conditions, and options to manage your refactorings along with delivery of business value to your Customers.

  1. December 11th, 2008 at 01:21
    Reply | Quote | #1

    You’ve made a great set of things to think about when refactoring!

    I feel like there is a term I heard once. Some concept of distance . . . like: the further you refactor from the point at which you are injecting functionality, the more protective you should be of your refactoring budget. THis is because the greater the distance, the more likely there is a later moment that refactoring can happen.

    But definitely fire when you see the whites of their eyes.

    Lance Kind