CMD Guide
HomeOO & Low-Level DesignBehavioral

Template Method Pattern

Template Method works because a non-overridable method in a base class fixes the order of an algorithm's steps and calls each step through a virtual method, so subclasses can replace what a step does but never the sequence or the wiring between steps. The control flow lives once, in the parent; the variation lives in the children. This is the literal Hollywood Principle — "Don't call us, we'll call you": the subclass never drives the algorithm, the parent's template method calls down into the subclass's overrides at the moments it chooses.

The mechanism, concretely

You have three report formats — CSV, HTML, PDF — and all three follow the same arc: collect → process → format → print. Only the three middle behaviours differ per format; the order and the printing never do. Put the arc in one final method on an abstract ReportGenerator, declare the varying steps abstract, and let each subclass fill them in. The base class owns the skeleton; the subclass owns the muscle.

diagram
diagram

Worked trace with real values

Run new CSVReportGenerator().generateReport() over a tiny two-line raw feed. The base method drives; the subclass supplies the per-step behaviour. Follow the value as it threads through.

StepDefined inInputOutput
collectData()CSV subclass"id,amt\n7,42\n9,13"
processData(raw)CSV subclassthat raw string2 parsed rows; running total = 42 + 13 = 55
formatReport(rows)CSV subclass2 rows + total"id,amt\n7,42\n9,13\nTOTAL,55"
printReport(report)base classthat CSV stringwrites 4 lines to stdout

Swap in HTMLReportGenerator and only the three middle outputs change — collectData() might hit a REST endpoint, formatReport() emits <table>…<tr>…55</tr></table> — but step 4 and the 1→2→3→4 order are byte-for-byte identical because they live in the parent.

The two guardrails the catalog version forgets

A catalog drawing of Template Method shows the skeleton and the abstract steps and stops. Two practical mechanisms make it actually safe to ship:

1. Lock the skeleton with final

The whole value proposition — "the order is fixed" — is only enforced if a subclass cannot override the template method. Declare it final (Java/C++) or document it as sealed. Without this, a subclass can override generateReport(), reorder the steps, or skip printReport(), and you have silently lost the invariant the pattern existed to protect.

2. Use hook methods for optional steps

Not every step is required by every subclass. A hook is a step the base class implements with a sensible default (often empty, or a boolean that returns true) so overriding is optional. The template method calls the hook; subclasses that care override it, the rest inherit the no-op. This is how you add optional behaviour without forcing every subclass to write empty methods.

Here is the report generator made correct — template method final, one abstract step set, and a boolean hook that lets a subclass opt into a footer:

public abstract class ReportGenerator {

    // Skeleton — FINAL so no subclass can reorder or skip steps.
    public final void generateReport() {
        String raw       = collectData();
        Rows   processed = processData(raw);
        String report    = formatReport(processed);
        if (includeFooter()) {            // hook call site
            report += formatFooter(processed);
        }
        printReport(report);              // shared, not overridable
    }

    // Required steps — subclasses MUST supply these.
    protected abstract String collectData();
    protected abstract Rows   processData(String raw);
    protected abstract String formatReport(Rows processed);

    // HOOK: default behaviour, override is OPTIONAL.
    protected boolean includeFooter() { return false; }
    protected String  formatFooter(Rows r) { return ""; }

    // Shared step — defined once, reused by all.
    private void printReport(String report) {
        System.out.println(report);
    }
}

class CSVReportGenerator extends ReportGenerator {
    @Override protected String collectData()            { return "id,amt\n7,42\n9,13"; }
    @Override protected Rows   processData(String raw)   { return Rows.parseCsv(raw); }
    @Override protected String formatReport(Rows r)      { return r.toCsv(); }
    @Override protected boolean includeFooter()          { return true; }      // opts in
    @Override protected String  formatFooter(Rows r)     { return "\nTOTAL," + r.sum(); }
}

class HTMLReportGenerator extends ReportGenerator {
    @Override protected String collectData()            { return Api.fetch("/sales"); }
    @Override protected Rows   processData(String raw)   { return Rows.parseJson(raw); }
    @Override protected String formatReport(Rows r)      { return r.toHtmlTable(); }
    // inherits includeFooter() == false: no footer, zero boilerplate.
}

Why the naive version is wrong

The original page left generateReport() as a plain public method and had no hook. That compiles, but it leaks the invariant: a junior dev writing PDFReportGenerator can legally write @Override public void generateReport() and call formatReport() before processData() — the compiler is happy, the bug is silent, and the "skeleton" the pattern promised no longer exists. Marking it final turns that mistake into a compile error. And without a hook, an optional footer forces every subclass to implement an empty formatFooter() — the boilerplate the pattern was supposed to remove.

The stakes are highest when the order is the safety property. A payment flow whose skeleton is validate → authorize → capture must never let a subclass capture money before it authorizes; a compliance pipeline must never let a subclass emit before it redacts. A non-final template method lets exactly that happen silently — which is why "seal the skeleton" is a correctness requirement in those domains, not a style preference.

Pitfalls

When to use it — and when to reach for Strategy instead

Template Method and Strategy solve the same problem — vary part of an algorithm — but with opposite mechanics. Template Method varies steps by inheritance (compile-time, the variation is baked into a subclass). Strategy varies a whole algorithm by composition (run-time, you inject a behaviour object). The deciding question is when the variation is chosen and how many axes vary.

Template MethodStrategy
MechanismSubclass overrides stepsInject a behaviour object
Binding timeCompile-time (per subclass)Run-time (swap the object)
Controls the flowThe base class (Hollywood)The client / context calls the strategy
VariesIndividual steps, one axisThe whole pluggable algorithm
CostInheritance coupling; class per variant; can't switch at runtimeExtra object + interface; flow no longer centralized

Decision signals

Concrete call: for the three report formats picked once at startup and sharing a strict collect→process→format→print arc, Template Method is the right tool — the order is the invariant worth protecting, and you'll never need to swap formats mid-run. The moment a requirement appears like "any data source paired with any output format, chosen by a config flag at runtime," stop subclassing and inject a DataSource strategy and a Formatter strategy instead.

One-liner: choose Template Method when the skeleton is sacred and variants are few and compile-time; prefer Strategy when behaviour must be swapped at runtime or varies on more than one axis.

Takeaways


Re-authored and deepened for this guide. Sources: Gamma, Helm, Johnson & Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software (1994), the original Template Method and Hollywood Principle discussion; Refactoring.Guru, "Template Method"; Freeman & Robson, Head First Design Patterns, 2nd ed. (hook methods and the Strategy contrast); Joshua Bloch, Effective Java, 3rd ed., Item 19 (designing for inheritance, the constructor-calling-overridable-method trap) and Item 18 (favor composition over inheritance). Java framework examples cross-checked against the JUnit, Jakarta Servlet, and Spring AbstractController APIs.

🤖 Don't fully get this? Learn it with Claude

Stuck on Template Method Pattern? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Template Method Pattern** (OO & Low-Level Design) and want to truly understand it. Explain Template Method Pattern from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Template Method Pattern** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Template Method Pattern** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Template Method Pattern** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes