Template Method Pattern

Fix the order of an algorithm's steps in a base class and let subclasses fill in the steps that differ.

Overview

The problem: the same steps, different details

Three importers read sales data from CSV files, JSON files and a database. Each one does the same four things in the same order: open the source, read the rows, clean them, write a summary. Only the first two steps differ. Written as three separate classes, the shared steps are copied three times, and a fix to the cleaning rule has to be made in three places.

  • Open — open the file — open the file — connect
  • Read rows — split lines on commas — parse an array — run a query
  • Clean rows — same — same — same
  • Summarize — same — same — same

Two rows of the table vary. Two are the same. The Template Method pattern keeps the shared rows and the order in one place.

The pattern

Template Method is one of the 23 patterns in the 1994 Gang of Four book (Gamma, Helm, Johnson and Vlissides). A base class has one method, the template method, that runs the steps in a fixed order. Each step is a method the subclass can supply. Steps come in three kinds.

  • Fixed step — Base class, concrete — No, and should not — clean rows, summarize
  • Required step — Base class, abstract — Yes — open, read rows
  • Hook — Base class, with a default (often empty) — Optional — after import, log a line

The base class calls the subclass, not the other way around. Application code calls run() and never the steps directly.

A runnable example

The row with a zero or negative amount is dropped by the shared cleaning step in both importers. That is the point: the rule lives once. Python's abc module refuses to create an Importer while open and read_rows are still abstract, so a subclass that forgets a required step fails at construction, not deep inside run().

Where you have already used it

Frameworks are built on this pattern, which is why it is worth knowing by name.

  • Python unittest — TestCase.run() — setUp runs right before each test method and tearDown right after it
  • Java InputStream — read(byte[], off, len) — The base class implements it by calling the abstract single-byte read() repeatedly
  • Jakarta Servlet HttpServlet — service() — It dispatches to doGet, doPost and the other doXxx methods; the docs say there is almost no reason to override service itself

The last row shows the pattern's rule of thumb in a real API: override the steps, never the template.

Template Method compared with Strategy

Both let you vary part of an algorithm. Template Method does it with inheritance. Strategy does it with an object you pass in.

  • Mechanism — Subclass overrides steps — Context holds a strategy object
  • What varies — Some steps, order is fixed — The whole algorithm
  • When it is chosen — At class definition — At runtime, can be swapped
  • Number of variants at once — One per object (its class) — Any mix; a context can hold several strategies
  • Extra objects — None — One per strategy
  • Testing a variant alone — Needs the base class — The strategy is a plain object

Choose Template Method when the order of steps is the thing you want to protect. Choose Strategy when callers need to swap behavior while the program runs, or combine variants.

Locking the skeleton

The pattern only works if subclasses cannot rearrange the steps. Languages give you different amounts of help.

  • Java — Declare it final; the language specification says a final method cannot be overridden or hidden
  • C++ — Leave it non-virtual
  • Python — typing.final marks it for type checkers only; the docs say there is no runtime checking, so rely on review and tests

What you will be able to do

  • Spot duplicated pipelines that differ in one or two steps and collapse them into one base class.
  • Name the three kinds of steps (fixed, required, hook) and choose the right one for each.
  • Explain why frameworks call your code rather than the reverse.
  • Argue Template Method against Strategy for a concrete case.
  • Keep the template method from being overridden, and say what your language can and cannot enforce.

Interview questions

  • Show the smell Template Method fixes, and the fix.
  • What is a hook, and how is it different from an abstract step?
  • When would you refactor a Template Method into a Strategy?
  • How do you stop a subclass from breaking the algorithm?
  • Why do frameworks use Template Method so much?

Sign up free to read the full topic

More Low-Level Design topics

Start free on Cariara · Coding problems · System design studio