Sunday, July 5, 2009

Refactoring vs. Re-architecting

I was recently gave a talk about refactoring. Beforehand I was asked to include something about "refactoring on a small scale" and "refactoring on a large scale". And how the two compare. I sort of just accepted that at first, but while preparing the talk I realised that "refactoring on a large scale" doesn't really make a lot of sense: Refactoring is about doing code changes that enhances readability, but doesn't change the observable behaviour of the software. That works out really well for localized changes such as extracting a method, renaming something, extracting an interface etc. But large scale changes (like splitting a single-process-application into several processes working together or moving from a voluntary scheduling scheme to a preemptive scheme) are very different beasts. Such changes aren't just large scale refactorings, they are re-architectings, and very different rules apply to the two.

Contrasting refactoring and re-architecting
To contrast the two let me list some important characteristics of refactoring:
  • Observable behaviour is not changed
  • The goal is to improve readability
  • Refactoring is pretty safe when you have good unit tests around the refactored code
  • Refactoring should be applied in an incremental fashion as a series of small steps
  • Refactoring can usually be done pretty quickly. I.e. the cost is low.
  • Refactoring helps keep the code base clean, which in turn helps keep the team velocity up (this is the real motivation for refactoring)
By contrast I find the following to be some of the important characteristics of re-architecting:
  • Re-architecting is usually done to improve one or more non-functional aspects, such as performance, scalability, availability, etc.
  • Re-architecting thus changes the observable behaviour
  • Re-architecting can't practically be done through a series of small steps. It must be done in a couple of big steps followed by a long series of small (refactoring) steps
  • The big steps are risky
  • The big steps are expensive/time consuming
  • Unit tests don't offer much help when doing the big steps
  • Re-architecting requires all levels of tests to be successful (integration, system, functional, non-functional, automated, manual)
To conclude I think that re-architecting is risky business that should only be done after thorough analysis of the cost vs. the benefit of doing the re-architecting. It's not "just" refactoring on a larger scale. That makes it sound too easy.