Back to Design Pattern Course

Design Pattern Course

Template Method is a Behavioral Design Pattern.

Template Method defines the skeleton of an algorithm in a base class method, and defers certain steps of that algorithm to subclasses. Subclasses provide their own implementations of those steps, but they cannot change the overall structure or order of the algorithm — the template method itself is declared final to enforce this.

This is ideal when you have a fixed overall process that must always follow the same sequence of steps, but where the details of individual steps vary by use case. Rather than duplicating the common structure in every subclass, the invariant structure lives once in the base class.

public abstract class DataRenderer { // The template method — algorithm structure is fixed public final void render() { String data = readData(); String processedData = processData(data); System.out.println(processedData); } // Steps deferred to subclasses protected abstract String readData(); protected abstract String processData(String data); }
public class XMLDataRenderer extends DataRenderer { @Override protected String readData() { return "xml data"; } @Override protected String processData(String data) { return "processed " + data; } }
public class TextDataRenderer extends DataRenderer { @Override protected String readData() { return "text data"; } @Override protected String processData(String data) { return "processed " + data; } }
public class Main { public static void main(String[] args) { DataRenderer renderer = new XMLDataRenderer(); renderer.render(); renderer = new TextDataRenderer(); renderer.render(); } }

Output

processed xml data
processed text data

The template method render() is marked final so no subclass can override and change the algorithm's structure — only the individual abstract steps can be overridden.

Template Method also optionally supports hook methods — non-abstract methods in the base class with a default (usually empty) implementation that subclasses may optionally override to inject behaviour at specific points in the algorithm. This is a commonly-omitted part of the pattern that's worth knowing, since it's used heavily in frameworks like Spring:

public abstract class DataRenderer { public final void render() { beforeRender(); // hook — optional for subclasses to override String data = readData(); String processedData = processData(data); System.out.println(processedData); afterRender(); // hook — optional for subclasses to override } protected abstract String readData(); protected abstract String processData(String data); // Hooks — do nothing by default; subclasses may override if needed protected void beforeRender() {} protected void afterRender() {} }

The Template Method pattern is one of the most widely used patterns in Java frameworks. Spring's AbstractController, JdbcTemplate, AbstractBeanFactory, and many other classes follow this pattern — they define a fixed processing pipeline and let you plug in the varying parts by extending or supplying callback implementations. Hibernate's SessionFactory lifecycle, JUnit's setUp()/tearDown()/runTest() flow, and Servlet's init()/service()/destroy() lifecycle are all Template Method in practice.

The important modern note: Template Method requires inheritance, which introduces tight coupling between the base class and its subclasses ("fragile base class" problem — changing the base class's non-abstract methods can silently break subclasses). Modern frameworks increasingly prefer Strategy (composition) over Template Method (inheritance), using functional interfaces or lambdas as the "step" implementations rather than forcing subclassing. Spring's JdbcTemplate with lambda-based RowMapper, and Comparator-based sorting, are examples of this shift. Know both patterns and when each is appropriate.

Advantages

  • Eliminates code duplication: the invariant algorithm structure is defined once in the base class.
  • Enforces a consistent algorithm structure across all subclasses — subclasses can't accidentally reorder steps.
  • Only the variable parts need to be overridden, reducing the amount of code subclasses must implement.

Disadvantages

  • Relies on inheritance, which can produce tight coupling and fragility as the base class evolves.
  • The sequence of abstract methods called in the template method may not be obvious to someone reading a subclass in isolation — you have to look at the base class to understand the full flow.
  • Can be harder to follow than composition-based approaches when the class hierarchy grows deep.

Template Method Pattern Examples in the JDK

  • All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader, and java.io.Writer that call abstract methods — e.g., java.io.InputStream#skip() and java.io.InputStream#read().
  • java.util.AbstractList, java.util.AbstractSet, java.util.AbstractMap — provide skeletal implementations of the List, Set, and Map interfaces using Template Method; concrete subclasses only need to implement the abstract primitive methods (get(), size(), etc.) and the abstract class's non-abstract methods handle the rest.
  • javax.servlet.http.HttpServlet#service() — the template method that dispatches to doGet(), doPost(), doPut(), etc. based on the HTTP method.