design·lab

Behavioral pattern

Template Method

A base class fixes the skeleton of an algorithm and calls a few overridable steps — subclasses fill in the details, the sequence never changes.

✗ The problem

Two exporters, one copy-pasted skeleton

CSV and JSON exporters both do open → header → rows → close — the skeleton is duplicated, only the formatting differs.

class CsvExporter {
  export(rows) {
    open(file);                 // 1
    write("id,name\n");      // 2
    rows.forEach(r =>
      write(`${r.id},${r.name}\n`)); // 3
    close(file);                // 4
  }
}
class JsonExporter {
  export(rows) {
    open(file);                 // 1
    write("[\n");            // 2
    rows.forEach(r =>
      write(JSON.stringify(r))); // 3
    close(file);                // 4
  }
}
The shared algorithm is copy-pasted into every exporter. Fix a step (say, add a trailing newline) in one class and forget the other — now they drift.
✓ The pattern

Fix the skeleton once, override the steps

The base class owns export() — the template method — and calls hooks that subclasses override.

class Exporter {
  export(rows) {       // skeleton
    this.open();
    this.header();
    rows.forEach(r =>
      this.row(r));
    this.close();
  }
  header() {}  row(r) {}  // hooks
}
Exporter
export() — skeleton
↓ calls
header() · row(r)
overridable hooks
↑ override
CsvExporter
JsonExporter
✓ See it live

Same skeleton, different steps

Pick an exporter and run it. All four steps fire in the same order — only header() and row() change what they produce.

open()
header()
row(r)
close()
// click "Run export()" to see the output
skeleton: open → header → rows → close
✓ Takeaway

One skeleton, many fillings

  • Define the algorithm's skeleton once in the base class; let subclasses fill in specific steps — removes duplication (DRY).
  • Hollywood principle: "don't call us, we'll call you" — the base class calls your hooks, not the other way around.
  • vs. Strategy: Template Method swaps steps via inheritance at compile time; Strategy swaps a whole algorithm via composition at runtime.
  • Careful: inheritance is rigid — one base class, one chosen shape. Prefer Strategy when callers need to swap behavior at runtime.
🎯 Principle applied: Template Method is DRY for algorithms — the skeleton is written once — plus Open/Closed (subclasses extend via hooks; the base stays closed). It inverts control: the base calls your steps (Hollywood principle).