diff.expert
TechniquesExercisesReference
© 2026 diff.expertAn Arbiter course
Home/Techniques/Extract and Delegate
Technique 5

Extract and Delegate

Move it first, change it second.

←PreviousScaffold FirstNextBranch by Abstraction→

When to Use

You need to modify code that's tangled up in a larger file or module. The code you want to change is mixed in with unrelated concerns — UI state, form handling, API calls, component lifecycle — and making the modification inside that noise would produce an unreadable PR.

Moving it out first makes both the move reviewable (a reviewer can verify the pure refactor introduced no behavior change) and the subsequent modification reviewable (a reviewer can focus on just the logic change in its now-clean, isolated home). This technique is especially powerful when combined with tests — the extraction PR proves the move didn't break anything, giving confidence for the modification PR.

The Pattern

  • PR 1 — Extract: Move the code into its own file, module, class, or custom hook with zero behavior change. All imports and call sites are updated. Tests pass.
  • PR 2 — Modify: Change the now-isolated code. The diff is small and focused because the noise has been stripped away.

The discipline is in keeping PR 1 pure. No sneaking in "just a small fix" during the extraction — not even obvious ones. The extract PR is a pure move, nothing else.

Commit Sequence

How this looks in your git history:

Worked Example

A React component OrderPage.tsx has grown to 400 lines with order processing business logic mixed into event handlers and useCallback hooks. The team needs to modify the discount calculation logic, but it's tangled up with UI state management, form handling, and API calls.

We'll extract the business logic into a custom hook first, then modify the discount logic in its clean, isolated home.

1

PR 1: Extract order processing logic into useOrderProcessing hook

Move calculateSubtotal(), applyDiscount(), validateOrder(), and all related state into a new useOrderProcessing hook. OrderPage is left with only what belongs in a component: JSX and the hook call. The extracted code lands verbatim in src/hooks/useOrderProcessing.ts.

Every line of this PR is a pure move. The business logic is identical — nothing is added, removed, or changed. OrderPage's JSX is untouched. All existing tests pass without modification. What we've gained is an isolated target: the next PR can modify applyDiscount() without any component noise in frame.

src/components/OrderPage.tsx
line numberline content
2

PR 2: Update discount calculation to support percentage and fixed discounts

Now that applyDiscount() lives in its own file with no surrounding noise, the modification is surgical. We add a DiscountType union, extend the function signature, and add the fixed-discount branch.

The diff is 15 lines in a single file. A reviewer can read it in 30 seconds and immediately verify the logic: percentage discounts work as before; fixed-amount discounts subtract the flat amount from the subtotal; both are floored at zero. No component code in frame, no state management to parse through — just the function and its change.

src/hooks/useOrderProcessing.ts
line numberline content

Common Mistakes

Making "just a small fix" during the extract. Discipline matters — the extract PR is a pure move, nothing else. Even if you spot a bug or an obvious improvement during extraction, fix it in a separate PR. Mixing a fix with a refactor makes both changes harder to review and harder to revert independently.

Not running the full test suite after the extract to catch missed references or broken imports. The point of the extract PR is to prove nothing changed. If you haven't verified this with a green test run, you haven't actually made a safe move — you've just moved code and hoped for the best.

Extracting too much or too little. Extract exactly what you need to modify, not the entire file's contents. The goal is isolation for the specific change, not a general refactoring project. If you're extracting things you don't intend to touch in PR 2, you're doing unnecessary work that adds risk to the extract PR.

←PreviousScaffold FirstNextBranch by Abstraction→
← All techniques