← IndexEntry № 176·coding

Refactor a long, tangled function into smaller, testable units

Breaks an overgrown function into smaller, single-responsibility units while preserving behavior and the public signature.

Optimized for
ChatGPTClaude
§ When to use this

Long functions are where bugs hide and onboarding slows down. The hard part of refactoring is doing it safely—changing structure without changing behavior—and most AI 'refactors' quietly alter the public signature or drop an edge case. This prompt forces a behavior-preserving approach: it pins the public signature so callers keep working, asks for single-responsibility extractions, and demands that hidden side effects be flagged rather than silently moved around. It works best when you give the model the actual code plus any hard constraints (no new dependencies, must stay synchronous, keep the same error type). Because it asks for a one-line explanation per extraction and a change summary, you get a reviewable diff rather than a mystery rewrite. Use it as a first pass before you run your test suite; the model is a refactoring assistant, not a substitute for the green checkmark. Pair it with the unit-test prompt so you have a safety net before and after the change.

§ The Prompt— fill in the fields, then copy or open in a tool
§ Customize0/4 fields filled
your prompt — fill the fields above
You are an expert software engineer who specializes in safe, behavior-preserving refactoring. I will give you a function written in [LANGUAGE] that has grown too long and does too much. Refactor it into smaller, well-named functions with clear single responsibilities, without changing observable behavior. Preserve the existing public signature [PUBLIC_SIGNATURE] so callers do not break. Extract pure helpers where possible, remove duplication, and flag any hidden side effects you find. Explain each extraction in one line. Honor these constraints: [CONSTRAINTS]. Here is the function:

[FUNCTION_CODE]

Return the refactored code first, then a short bullet list of what changed and why.
Open with your prompt →ChatGPTClaudeSends your filled-in prompt straight into a new chat.
§ Example Output

What you can expect back

```ts
function calculateInvoice(order: Order): Money {
  const subtotal = order.items.reduce((sum, item) => sum + lineTotal(item), 0);
  const total = clampToZero(applyCoupon(subtotal, order.coupon));
  return { amount: total, currency: order.currency };
}

function lineTotal(item: LineItem): number {
  if (!item.sku) throw new ValidationError('missing sku');
  const gross = item.price * item.qty;
  return item.qty >= 10 ? gross * 0.9 : gross;
}

function applyCoupon(amount: number, coupon?: string): number {
  return coupon === 'SAVE5' ? amount - 5 : amount;
}

const clampToZero = (n: number) => (n < 0 ? 0 : n);
```

Changes:
- Extracted lineTotal: isolates validation + bulk discount per item.
- Extracted applyCoupon: separates discount policy from summation.
- Added clampToZero helper for the negative-total guard.
- Public signature and ValidationError type unchanged; no new deps.

Illustrative example — your results will vary by tool and inputs.

§ Pro Tips

Get sharper results

  • 01Run your test suite immediately before and after—this prompt preserves behavior by intent, not by proof.
  • 02If the function has side effects (DB writes, logging), list them in [CONSTRAINTS] so they aren't reordered.
  • 03Ask for the diff in a second message if the rewrite is large, so review stays focused.
  • 04Refactor in small batches; feed one function at a time rather than a whole file.
§ Variations

Adapt it for your case

Reduce cyclomatic complexity

Add 'Prioritize reducing branching depth; replace nested conditionals with guard clauses or a lookup table.'

Make it testable

Add 'Extract impure operations behind injectable parameters so the core logic can be unit-tested without mocks.'

Best For — Roles
Tags#refactoring#clean-code#maintainability
§ FAQ

Common questions

Will it change my function's behavior?

The prompt instructs behavior-preserving refactoring, but always confirm with your existing tests—treat the output as a proposal, not a guarantee.

Can I refactor an entire file at once?

Better not. Feed one function at a time; large multi-function rewrites are harder to review and more likely to drift.

What if it suggests a new dependency I don't want?

List 'no new dependencies' in [CONSTRAINTS]; the prompt already respects stated constraints and will work within the standard library.

§ Related Entries

You may also need