Refactoring techniqueComposing Methods
Split Temporary Variable
Give each distinct purpose its own variable when one local is reassigned to hold unrelated intermediate values.
- Also known as
- Split Variable
Problem
One local variable is reused for several unrelated values: first a count, later a percentage, later a label. Each reader has to track which meaning is live at which line, and extracting any fragment drags the shared variable along.
Solution
Declare a separate, well-named const for each purpose. Loop accumulators (sum += x) and collecting variables are the exception: they hold one meaning that grows.
Before
function summarizeFunnel(events: AnalyticsEvent[]): string {
let temp = events.filter((e) => e.type === "visit").length;
const visits = temp;
temp = events.filter((e) => e.type === "signup").length;
const signupRate = visits === 0 ? 0 : temp / visits;
temp = events.filter((e) => e.type === "purchase").length;
const purchaseRate = visits === 0 ? 0 : temp / visits;
return `visits=${visits} signup=${(signupRate * 100).toFixed(1)}% purchase=${(purchaseRate * 100).toFixed(1)}%`;
}After
function summarizeFunnel(events: AnalyticsEvent[]): string {
const visits = events.filter((e) => e.type === "visit").length;
const signups = events.filter((e) => e.type === "signup").length;
const purchases = events.filter((e) => e.type === "purchase").length;
const signupRate = visits === 0 ? 0 : signups / visits;
const purchaseRate = visits === 0 ? 0 : purchases / visits;
return `visits=${visits} signup=${(signupRate * 100).toFixed(1)}% purchase=${(purchaseRate * 100).toFixed(1)}%`;
}Why
- Each name states one meaning for its whole lifetime.
constlets the compiler reject accidental reassignment.- Fragments become independent, so Extract Method and Replace Temp with Query apply cleanly.
Steps
- Find the first assignment of the reused variable. Rename the variable at that assignment and its reads up to the next assignment. Declare it
const. - Compile and run the tests.
- At the next assignment, declare a new
constwith a name for that purpose and update the reads that follow it. - Repeat until each assignment has its own variable. Delete the original declaration if nothing uses it.
Watch out
- Don't split accumulators or loop counters whose reassignments all serve one meaning (
total += line.amount). - Check closures. A callback created earlier may capture the original variable and observe later values; splitting changes what it sees.
- If the variable is a function parameter, apply Remove Assignments to Parameters instead.
- There is no useful inverse. Merging unrelated values into one variable is the smell itself.
Related
- Helps with Long Method.
- Prepares for Replace Temp with Query and Extract Method.
- Remove Assignments to Parameters is the same fix for parameters.
Agent checklist
- Every reassignment served a different purpose; accumulators were left alone.
- Each new variable is
constand named for its meaning. - No closure captured the old variable and relied on later values.
- Tests pass.
Treats these smells
See also
- Remove Assignments to ParametersStop reassigning a function parameter inside its body; copy it into a local variable and work on that instead.
- Replace Temp with QueryMove the expression behind a temporary variable into its own method so every method in the class can ask for the value.
- Extract MethodMove a coherent fragment of a long function into its own well-named function and call it from the original place.
Original writing and examples. Topic coverage follows Refactoring.Guru, which explains this topic with its own illustrations.