Extract Variable

Symptom

A long expression in a conditional, return statement, or method argument that the reader must mentally parse — multiple operations on multiple inputs producing one value. The reader's rises because every read re-parses the full expression to derive its meaning, and debugging requires breakpoints inside the expression to inspect the intermediate value.

Goal

A complex expression earns a name that says what it represents in the domain. Readers resolve to one named token instead of re-evaluating the expression at every use; the binding's definition site is the only place the expression appears, and the named value is reusable in nearby code without restating the calculation.

Before the refactoring

if (order.qty * order.price - Math.max(0, order.qty - 500) * order.price * 0.05 > 1000) { /* ... */ }

After the refactoring

const basePrice = order.qty * order.price;
const bulkDiscount = Math.max(0, order.qty - 500) * order.price * 0.05;
if (basePrice - bulkDiscount > 1000) { /* ... */ }
Example source: Illustrative example written for this site; the refactoring itself is catalogued in Martin Fowler's Refactoring (Addison-Wesley, 2018), see the chapter on A First Set of Refactorings.
Pressure

Readers pay parsing cost every time; debugging the value requires breakpoints inside the expression; comments scatter to explain what subexpressions mean. The team's compounds across every reviewer who must re-parse the full expression to verify a change, and the same parsing happens at every call site that touches the expression.

Tradeoff

Over-extracting tiny expressions clutters scope with one-shot names; extract when the expression carries domain meaning the surrounding code can't speak. The team's can rise rather than drop if extractions don't earn their names, because every binding is one more name the reader must look up and the scope table grows with definitions that document nothing.

Relief

Reusable in nearby code; debugging shows the intermediate value; comments explaining the expression become unnecessary. The team's drops because adding a new use of the value is one reference to the existing name rather than restating the full expression, and bugs in the calculation surface at one binding site instead of N call sites.

Trap

Extracting every short expression — including ones already self-explanatory — clutters scope with one-shot names that obscure rather than reveal intent. The of scanning scope to find what each name binds rises faster than the per-expression comprehension cost drops, and the cure adds to scope-table navigation.