Skip to main content

Extract Function and Inline Function

What This Concept Is

Two inverse refactor moves from Fowler's catalog.

Extract Function: take a fragment of code and give it its own function, named after its intent. You extract even a single line if the name explains what better than the line shows.

Inline Function: take a function whose body is as clear as its name, or a function whose indirection is not paying off, and paste its body back at every call site.

These two are the most frequent moves in any refactor session. Every other move in the module depends on being able to do these cleanly.

Why It Matters Here

Most code-quality wins come from separating intention from implementation. A well-named extracted function lets the reader skip the body unless they care. A badly-named one is worse than inline code: it hides meaning behind a confusing name.

Inline Function is the pressure relief valve. You are allowed to extract tentatively, find that the name does not fit, and inline the extraction back. Time was not wasted; you learned something.

Concrete Example

Before (tangled inline):

function printOwing(invoice) {
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
let outstanding = 0;
for (const o of invoice.orders) outstanding += o.amount;
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
}

After Extract Function (×3):

function printOwing(invoice) {
printBanner();
const outstanding = calculateOutstanding(invoice);
printDetails(invoice, outstanding);
}
function printBanner() {
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
}
function calculateOutstanding(invoice) {
return invoice.orders.reduce((sum, o) => sum + o.amount, 0);
}
function printDetails(invoice, outstanding) {
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
}

Inline Function in reverse: if calculateOutstanding were only called once and its name was no more informative than the body, inlining would remove a needless indirection.

Common Confusion / Misconception

"Extracted functions should always be reused." No. Fowler's argument that won over reuse-based rules is the intention/implementation split. A one-line function whose name is longer than its body is still valuable if the name explains why.

Also: if you cannot think of a good name, that is a signal. Either the fragment does not have one coherent intent (do not extract yet), or you do not understand it yet (comprehension refactor first).

How To Use It

Mechanics for Extract Function:

  1. Create the new function, named after intent.
  2. Copy the fragment in.
  3. Pass in any local variables used but not assigned in the fragment.
  4. If a local is assigned inside the fragment, treat the extraction as a query returning its new value, or stop and do Split Variable first.
  5. Compile / lint. Run tests.
  6. Replace the fragment with a call to the new function. Run tests.

Mechanics for Inline Function:

  1. Check this is not a polymorphic method (overrides must remain).
  2. Find all callers.
  3. Replace each call with the body, testing after each.
  4. Remove the function definition.

Check Yourself

  1. Name two signals that say "extract this fragment" and two signals that say "do not."
  2. If your IDE's automated Extract Method produces a function with five parameters, what has that told you?
  3. When is Inline Function the right move on code you recently wrote?

Mini Drill or Application

Pick a 50-line function and extract it down to a top-level function that is 5-10 lines of named helper calls. Time yourself. Run tests after every extraction. If a test goes red, revert that one extraction and investigate why -- do not batch them.

Video and Lecture References

Article References

External Exercises

Depth Path

  • Read This Only If Stuck - Fowler chunks 038, 039, 040 (Extract Function parts 1-2, Inline Function)
  • Optional deep dive: chunk 059 (Move Statements into/out of Function) for when extraction is not quite right

Source Backbone

Refactoring is the canonical book backbone for this module. Use these sources after attempting the refactor and tests yourself.