Refactoring
Improve the design of working code without changing what the system does.
Context
Refactoring keeps implementation quality from decaying between releases.
See context and anti-pattern notes.
Inputs
I/O contract notes define required inputs and authority.
Process
Step 1: Choose One Structural Problem
Pick a focused target such as duplication, oversized functions, unstable seams, hidden dependencies, or naming that obscures intent. Define the invariant that must not change.
Avoid combining unrelated cleanup goals into one refactor.
Step 2: Strengthen the Behavioral Safety Net
Before moving code, verify the tests protect the behavior that matters. Add characterization or regression coverage first if the current suite would allow a silent behavior change.
Step 3: Refactor in Reversible Steps
Make the change as a sequence of small transformations:
- rename for clarity
- extract or inline with tests green
- move responsibilities to cleaner seams
- remove duplication after the new shape is proven
Run the relevant tests after every step.
Step 4: Prove the Design Actually Improved
Before review, state what got better: smaller surface area, clearer boundaries, lower duplication, simpler control flow, or safer extension points. If you cannot name the gain, the change is probably unnecessary.
Outputs
Produce only declared outputs at their documented quality boundary.
Quality Gate
- Tests prove behavior stayed stable
- The refactor addresses a concrete structural problem
- The change is narrow, reviewable, and reversible
- Complexity, coupling, or duplication is measurably lower
- No opportunistic feature work is mixed into the refactor