Template Method Pattern: Mastering Algorithm Skeletons in Scala

Explore Template Method in Scala, when a fixed algorithm skeleton still matters, and when higher-order functions or composition are a better fit than inheritance-based customization.

Template Method pattern: A behavioral pattern in which a fixed algorithm skeleton is defined once, while selected steps are left open for customization.

Scala can implement Template Method cleanly, but it also gives you alternatives that are often better than inheritance. That makes this page less about “how to subclass correctly” and more about when a stable skeleton truly deserves to exist.

The Pattern Is About Protected Sequencing

Template Method is useful when a workflow must preserve a fixed order:

  • load, validate, transform, persist
  • parse, normalize, analyze, report
  • authenticate, authorize, execute, audit

The important design force is not reuse alone. It is that the sequence itself is part of the contract, while some steps vary.

Classic Scala Form: final Template, Open Steps

 1abstract class ImportJob:
 2  final def run(path: String): Unit =
 3    val raw = load(path)
 4    val validated = validate(raw)
 5    val transformed = transform(validated)
 6    persist(transformed)
 7    afterPersist(transformed)
 8
 9  protected def load(path: String): String
10  protected def validate(raw: String): String = raw
11  protected def transform(raw: String): Vector[String]
12  protected def persist(rows: Vector[String]): Unit
13  protected def afterPersist(rows: Vector[String]): Unit = ()

This keeps the overall structure stable while allowing subclasses to refine the variable steps. The final template method matters because it preserves the sequencing rule.

In Scala, Composition Is Often Better

Scala frequently replaces Template Method with higher-order functions or small services:

 1def runImport(
 2    load: String => String,
 3    validate: String => String,
 4    transform: String => Vector[String],
 5    persist: Vector[String] => Unit
 6)(path: String): Unit =
 7  val raw = load(path)
 8  val checked = validate(raw)
 9  val rows = transform(checked)
10  persist(rows)

This is still “template-like,” but without inheritance. It is often easier to test, combine, and evolve.

When Template Method Still Helps

Use the classic pattern when:

  • the algorithm skeleton must be protected
  • subclass authors are expected to customize only specific steps
  • hook methods and default behavior are part of the framework contract
  • the surrounding code is already organized around inheritance

Framework internals, test harnesses, import jobs, and lifecycle-bound processors are common fits.

When To Prefer Strategy or Composition Instead

Template Method is weaker when the variation itself should be passed in explicitly or mixed and matched at runtime. In that case:

  • Strategy is better for interchangeable policy choice
  • plain function composition is better for assembling pipelines
  • ADTs plus pattern matching are better when the “steps” are really different cases of data

The moment you find yourself subclassing only to inject one small behavior, Template Method may already be too heavy.

Common Failure Modes

Inheritance-Only Thinking

The team uses Template Method because it is familiar, even though a few passed functions would make the workflow clearer.

Too Many Hooks

The template class grows so many overridable methods that the skeleton is no longer clear. At that point the pattern has lost its point.

Hidden Side Effects in Subclasses

The top-level sequence looks stable, but subclasses quietly add unrelated side effects that make the real lifecycle hard to review.

Practical Heuristics

Use Template Method when one protected algorithm skeleton is genuinely the contract. Mark the template as stable, keep hooks small, and prefer composition first in modern Scala unless inheritance is carrying real framework meaning.

Knowledge Check

Loading quiz…
Revised on Thursday, April 23, 2026