Refactoring
Disciplined restructuring of code without changing observable behavior, per Fowler.
Refactoring is the disciplined technique of restructuring an existing body of code, altering its internal structure without changing its external behavior. The practice was substantially codified by Martin Fowler in Refactoring: Improving the Design of Existing Code (1999, 2nd ed. 2018), which catalogued specific refactoring transformations (Extract Method, Inline Method, Move Function, Replace Conditional with Polymorphism, etc.) with mechanical step-by-step procedures designed to be safe even when applied to unfamiliar code. The methodology rests on three pillars: behavior preservation (refactorings don't change what the code does, only how), small steps (each refactoring is small enough to verify), and continuous testing (an automated test suite verifies behavior preservation at each step). Refactoring complements TDD and is essential to the iterative-design approach in XP and broader agile practice — without refactoring, code quality degrades over time as new functionality is added, eventually requiring rewrite. Modern IDE support has made many of Fowler's mechanical procedures into single-keystroke operations, substantially lowering the cost of small refactorings. Joshua Kerievsky's Refactoring to Patterns (2004) extended Fowler's catalog with refactorings targeted at specific Gang of Four design patterns.
Core components
- Behavior-preserving structural transformations
- Catalog of named refactorings (Extract Method, Inline, Move, Rename, Replace Conditional with Polymorphism, etc.)
- Mechanical step-by-step procedures
- Continuous testing as safety net
- Connection to TDD red-green-refactor cycle
- IDE refactoring tooling support
- Code smells as indicators of refactoring opportunity
- Refactoring to Patterns (Kerievsky extension)
- Distinction from rewriting (which changes behavior or starts from scratch)
Primary use case
Software maintenance and evolution; foundation for sustainable code quality; essential complement to TDD and continuous integration; basis for iterative design (you can change your mind about design as you learn); reference framework in software craftsmanship; standard practice in modern professional software development.
Common criticisms
- Refactoring without comprehensive automated tests is dangerous — Fowler's procedures assume the test suite catches behavior changes, which is often not the case in legacy code
- refactoring is often deferred indefinitely under delivery pressure, leading to design degradation that eventually requires costly rewrite (the practice exists precisely to prevent this but only works if continuously practiced)
- some refactorings change observable behavior in ways the catalog doesn't always make obvious (timing, error messages, edge cases — see Hyrum's Law)
- IDE-supported refactorings vary in safety across languages — refactorings safe in statically-typed languages may not be safe in dynamic languages
- can become refactoring-as-procrastination when used to avoid harder design decisions
- large 'refactoring' projects that change architecture are often actually rewrites mislabeled as refactoring
- effort estimation for refactoring is notoriously difficult.
Lineage
- Parent of
- The Boy Scout Rule
- Child of
- Extreme Programming
- Siblings
- Test-Driven Development, The Boy Scout Rule
- Derived from
- Extreme Programming