Refactoring techniqueComposing Methods
Inline Method
Replace calls to a function whose body is as clear as its name with the body itself, then delete the function.
- Also known as
- Inline Function
Problem
A function adds a name but no meaning. Its body is one obvious line, or it only forwards to another call. Readers jump to the definition and find nothing they could not have read in place.
Solution
Put the body at each call site and delete the function. Do this also as a reset: inline a tangle of badly split helpers back into one function, then extract them again along better lines.
Before
class SessionPolicy {
constructor(private readonly maxIdleMinutes: number) {}
isExpired(session: Session, now: Date): boolean {
return this.idleMinutes(session, now) > this.limit();
}
private idleMinutes(session: Session, now: Date): number {
return minutesBetween(session.lastSeenAt, now);
}
private limit(): number {
return this.maxIdleMinutes;
}
}After
class SessionPolicy {
constructor(private readonly maxIdleMinutes: number) {}
isExpired(session: Session, now: Date): boolean {
return minutesBetween(session.lastSeenAt, now) > this.maxIdleMinutes;
}
}Why
- Fewer hops to understand the code. The condition is visible in one line.
- Removes indirection left over from earlier refactorings or from speculative "maybe we'll override this" hooks.
- Inlining a cluster of small, poorly named helpers is often the fastest route to re-extracting good ones.
Steps
- Confirm the function is not polymorphic: no subclass overrides it and no interface requires it. If one does, stop.
- Find every call site. Include reflection, string-based dispatch, templates and tests.
- Replace one call with the body, substituting arguments for parameters. Run the tests.
- Repeat for each remaining call site.
- Delete the function. Run the tests again.
Watch out
- Don't inline a method that subclasses override or that is part of a public API. Callers outside your codebase break.
- Don't inline when the body is long or used in many places. You trade one name for duplicated code; that is the Duplicate Code smell.
- If arguments have side effects or are expensive, substituting them into the body more than once changes behavior. Assign them to a local first.
- Recursive functions and those with several
returnstatements need care; turning them into inline code may require restructuring. - The inverse is Extract Method. Extract when the body is less clear than a name would be.
Related
- Fixes Speculative Generality, Middle Man and Lazy Class when the class shrinks to forwarding methods.
- Inverse: Extract Method.
- Remove Middle Man and Inline Class apply the same idea at class level.
- Inline Temp is the variable-level counterpart.
Agent checklist
- No override, interface contract or external caller depends on the method.
- All call sites were found, including dynamic and test references.
- Arguments with side effects are evaluated exactly once after inlining.
- The inlined code is no harder to read than the call was.
- The method is deleted and tests pass.
Treats these smells
- Speculative GeneralityAbstractions, hooks and parameters built for future needs that never arrived make code harder to read without serving any current use.
- Middle ManA class mostly forwards calls to another object and adds nothing. Let clients talk to the real object or fold the wrapper away.
- Lazy ClassA class does too little to justify the file, name and indirection it costs; fold it into its caller or delete it.
See also
- Extract MethodMove a coherent fragment of a long function into its own well-named function and call it from the original place.
- Remove Middle ManLet clients call the delegate directly when a class does little more than forward calls to it.
- Inline TempReplace a temporary variable that holds a simple expression with the expression itself when the name adds nothing.
- Inline ClassFold a class that does too little into the class that uses it, moving its fields and methods across and deleting it.
Original writing and examples. Topic coverage follows Refactoring.Guru, which explains this topic with its own illustrations.