# When to Refactor

> Refactor right before you change code, while fixing a bug and during review. Skip it when the code is due for deletion or has no tests.

- kind: guide
- category: refactoring
- aliases: Refactoring triggers
- canonical: https://aipatterns.dev/guides/when-to-refactor
- inspired-by: https://refactoring.guru/refactoring/when

## The short answer

**Refactor the code you are about to change, right before you change it.** That is when the cost of bad structure is real and the benefit lands immediately. Refactoring code that nobody will touch again is spending money on a building scheduled for demolition.

## Good moments

### Before adding a feature

Read the area you need to change. If the feature would be awkward to add, first reshape the code so the feature becomes a small, obvious addition. Make the change cheap first, then make the cheap change.

Typical sequence:

1. The new payment method needs a fourth branch in a [Switch Statements](https://aipatterns.dev/refactoring/smells/switch-statements.md) block that already has three.
2. Apply [Replace Conditional with Polymorphism](https://aipatterns.dev/refactoring/techniques/replace-conditional-with-polymorphism.md) or extract a [Strategy](https://aipatterns.dev/design-patterns/strategy.md) map. Tests stay green.
3. Add the new method as one new class or function.

### When fixing a bug

A bug is evidence that the code is hard to understand. Before fixing it, restructure enough to make the bug visible: [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md) to name the steps, [Decompose Conditional](https://aipatterns.dev/refactoring/techniques/decompose-conditional.md) to name the conditions. Often the bug becomes obvious. Then write a failing test, fix, and commit the refactoring and the fix separately.

### The rule of three

The first time, write it. The second time you write something similar, note the duplication. The third time, extract the shared part. Two copies may diverge for good reasons; three copies are a pattern. See [Duplicate Code](https://aipatterns.dev/refactoring/smells/duplicate-code.md).

### During code review

Review is where a second reader finds names that mislead and functions that do too much. Small renames ([Rename Method](https://aipatterns.dev/refactoring/techniques/rename-method.md)) and extractions are cheap to apply while the author still has context.

### When you need to understand code

Renaming a variable once you understand what it holds stores that understanding in the code. The next reader, human or agent, does not need to rediscover it.

## Bad moments

- **The code works, is not changing and has no pending work.** Leave it. Ugly but stable code has zero interest.
- **The code is scheduled for deletion or replacement.** Spend the effort on the replacement.
- **There are no tests and you cannot add them cheaply.** Refactoring without verification is guessing. Add characterization tests first, or restrict yourself to IDE-automated, provably safe transformations (rename, extract with a tool).
- **You are close to a deadline and the change is not on the critical path.** Record the debt (see [Technical debt](https://aipatterns.dev/guides/technical-debt.md)) and come back.
- **The rewrite is honestly cheaper.** If the code is so broken that it does not work, refactoring has nothing to preserve. Restructuring assumes correct behavior worth keeping.
- **The task is not yours.** An agent asked to fix one bug should not restructure three unrelated modules. Scope creep makes diffs unreviewable.

## Decide in one pass

| Question | If yes | If no |
|---|---|---|
| Will you change this code in the current task? | Continue | Do not refactor |
| Do tests cover the behavior you will touch? | Continue | Add tests first, or stop |
| Would the task's diff be clearly smaller or safer after restructuring? | Refactor first | Make the change directly |
| Does the refactoring stay inside the files the task already touches? | Proceed | Note it, do not do it now |

## Signals in the code

The smell catalog lists symptoms worth acting on. The most common triggers:

- A function longer than a screen: [Long Method](https://aipatterns.dev/refactoring/smells/long-method.md).
- A change that needs edits in many files: [Shotgun Surgery](https://aipatterns.dev/refactoring/smells/shotgun-surgery.md).
- A method that uses another object's data more than its own: [Feature Envy](https://aipatterns.dev/refactoring/smells/feature-envy.md).
- The same group of three or four parameters passed everywhere: [Data Clumps](https://aipatterns.dev/refactoring/smells/data-clumps.md).
- Comments explaining what a block does: [Comments](https://aipatterns.dev/refactoring/smells/comments.md).

## Agent checklist

- [ ] The code you plan to refactor is in the path of the current task.
- [ ] Tests cover the behavior, or you added characterization tests first.
- [ ] You can state the concrete way the refactoring makes the task smaller or safer.
- [ ] The refactoring stays within the scope the user asked for; anything broader is reported, not done.
- [ ] Refactoring and behavior change land as separate commits or separate steps.
