Refactoring Techniques
Purpose
Refactoring is a controlled technique for improving the design of existing code — a series of small, behavior-preserving transformations. Each individual change is tiny, but a sequence of them can significantly restructure code while keeping it working at every step. This skill catalogs the named techniques and tells you when and how to apply each.
What is refactoring?
Refactoring changes the internal structure of code without changing its external behavior.
Two rules of the discipline:
- Don't refactor and add features at the same time. Separate the two into distinct steps (and ideally distinct commits).
- Keep tests green. Have working tests before you start; run them after each small step. If something breaks, you know the last tiny change caused it.
Refactor when code smells warrant it (see the companion code-smells skill), before adding a feature to ground you're about to touch, or when reviewing makes code hard to understand.
When To Use
Use this skill when the user asks to:
- Refactor code or restructure it without changing behavior.
- Perform a named technique ("extract this into a method", "pull this field up", "replace this switch with polymorphism").
- Treat a code smell and wants the concrete mechanics of the fix (pairs with the code-smells skill).
- Improve a method, class, or inheritance hierarchy for readability, testability, or reuse.
When to ease off
Refactoring is an investment, not an end in itself. Apply a lighter bar when the code is disposable (spike, generated boilerplate), when there's no test safety net and adding one isn't feasible right now, or under a time-critical hotfix. Don't refactor code you're about to delete. Prefer the smallest change that removes the pain over a sweeping restructure.
The Six Groups
Mechanics for every technique live in REFERENCE.md.
Composing Methods
Streamline methods, remove duplication, pave the way for further change. Overly long methods are the root of most evil.
- Extract Method · Inline Method · Extract Variable · Inline Temp · Replace Temp with Query · Split Temporary Variable · Remove Assignments to Parameters · Replace Method with Method Object · Substitute Algorithm
Moving Features between Objects
Safely move functionality between classes, create new classes, hide implementation details.
- Move Method · Move Field · Extract Class · Inline Class · Hide Delegate · Remove Middle Man · Introduce Foreign Method · Introduce Local Extension
Organizing Data
Handle data better — replace primitives with rich classes, untangle class associations for portability and reuse.
- Change Value to Reference · Change Reference to Value · Duplicate Observed Data · Self Encapsulate Field · Replace Data Value with Object · Replace Array with Object · Change Unidirectional Association to Bidirectional · Change Bidirectional Association to Unidirectional · Encapsulate Field · Encapsulate Collection · Replace Magic Number with Symbolic Constant · Replace Type Code with Class · Replace Type Code with Subclasses · Replace Type Code with State/Strategy · Replace Subclass with Fields
Simplifying Conditional Expressions
Conditionals accumulate complexity over time; these techniques fight back.
- Consolidate Conditional Expression · Consolidate Duplicate Conditional Fragments · Decompose Conditional · Replace Conditional with Polymorphism · Remove Control Flag · Replace Nested Conditional with Guard Clauses · Introduce Null Object · Introduce Assertion
Simplifying Method Calls
Make calls simpler and interfaces between classes easier to understand.
- Add Parameter · Remove Parameter · Rename Method · Separate Query from Modifier · Parameterize Method · Introduce Parameter Object · Preserve Whole Object · Remove Setting Method · Replace Parameter with Explicit Methods · Replace Parameter with Method Call · Hide Method · Replace Constructor with Factory Method · Replace Error Code with Exception · Replace Exception with Test
Dealing with Generalization
Move functionality along the inheritance hierarchy; create classes and interfaces; trade inheritance for delegation and back.
- Pull Up Field · Pull Up Method · Pull Up Constructor Body · Push Down Field · Push Down Method · Extract Subclass · Extract Superclass · Extract Interface · Collapse Hierarchy · Form Template Method · Replace Inheritance with Delegation · Replace Delegation with Inheritance
Workflow
- Ensure a test safety net. Confirm tests exist and pass before touching anything. If not, add characterization tests first.
- Identify the target — name the smell or the structural problem (cite the code-smells skill).
- Pick the technique from the catalog that addresses it.
- Apply in small steps, following the mechanics in REFERENCE.md. Compile/run after each step.
- Run tests after every step; if red, revert the last step.
- Commit the refactoring separately from any feature work.
Output Contract
When proposing a refactoring, state:
[technique] target → why (smell it removes) → ordered mechanics (REFERENCE.md#anchor)
Keep behavior identical. Call out explicitly if a step is not behavior-preserving (rare) so the user can add coverage.
Relationship to Code Smells
Smells tell you what is wrong; refactorings tell you how to fix it. The companion code-smells skill names each smell's treatments using the techniques cataloged here. When asked to "fix this smell", diagnose with code-smells, then apply the matching technique from this skill.