Template Method Pattern

« Back to Glossary Index

Description


The Template Method pattern defines the skeleton of an algorithm or operation in high-level steps. Users or subclasses can override or implement the behavior of specific steps within the algorithm, but are not able to modify the general algorithm flow itself.

This design pattern is categorized as a “behavioral class” pattern in the Design Patterns book by Gamma et al., who summarize the pattern in this way:

Quote

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

Context

The intent of this pattern is to define and enforce the overall structure of an operation or algorithm, while allowing users or subclasses to refine, redefine, or implement specific steps. Users are not able to modify the overall algorithm or its structure (for that, you would use the Strategy pattern).

This pattern makes use of Inversion of Control. The library, framework, or base class controls the operation, but it invokes functions in user code or subclasses which implement individual steps.

Problem

The Template Method pattern can be used to address two common situations that arise in software development.

As you develop a system, you will often naturally develop functions or classes that are largely duplicated in their functionality, but varying in small individual implementation details. This often happens as system grows because a specific operation or algorithm needs to be extended or customized for different specific use cases. In other cases, it happens because existing library or SDK code needs to be adjusted to be better suit your system’s needs. In any case, wouldn’t it be preferable for the common code to be kept in a single place, eliminating the duplicated behavior across all of the implementations, while still preserving the ability to customize individual operational steps for specific use cases?

Note

That is the original problem that the Template Method pattern was targeted at.

Embedded software developers deal with the same problem described above, but also have another common challenge. Every embedded device is essentially unique in its combination of hardware and software dependencies: different processors, vendor SDKs, OSes, libraries, frameworks, hardware components, and PCB layouts contribute to completely unique products. A large amount of embedded code could be portable and reusable, but implementations are often tightly coupled to a unique platform due to the need to account for the unique hardware and software makeup of that platform. Wouldn’t it be better to structure embedded software in such a way that users could implement or override specific steps (such sending and receiving data over a SPI or I2C bus) to support their unique hardware/software dependencies, allowing the implementation to remain independent of a specific platform?

Forces

In these scenarios, you are trying to balance control with customization while minimizing duplication. You need to define an overall operation, but users or subclasses need the ability to vary individual steps in the operation. The naive approach is to customize the operation by making a copy of it and varying the steps as necessary. However, this leads to duplication of the common steps of the algorithm, and if a change has to be made it must be propagated to all of the implementations. There is also no enforcement of the operation across the duplicate implementations: they can deviate in behavior over time.

With the Template Method pattern, you can enforce control of the operational flow while giving clients the ability to customize individual steps of the operation. Common code can be kept in a single location, eliminating duplication. Thanks to the eliminated duplication and customizability, you increase the possibility of reusing the code for new purposes.

Reuse is also improved by the reduction of coupling that this pattern enables, which is specifically beneficial to the embedded scenario above. Embedded software is often tightly coupled to the underlying hardware/software platform. However, we can leverage the customization of individual steps to allow users to implement functionality specifically for their system outside of the primary implementation. This also improves the portability of the software.

Solution

In a base class, library, or framework, define a Template Method which contains the invariant code (the common code) for the overall algorithm or operation. The operation is broken down into a series of steps. The distinct steps, especially those that can or must be customized, are factored into individual functions. Individual steps may be controlled completely by the implementation, or they may be customizable by the user.

The customizable steps (sometimes called “helper methods” or “customization points”) of a Template Method can be further categorized in the following way:

  • Abstract steps, which do not supply a default implementation and must be provided by every subclass or application
  • Optional steps, which supply a default implementation but can be overridden if desired
  • Hooks, which are optional steps with an empty body that provide additional extension points for an algorithm
    • Hooks are often placed before and after crucial steps of an operation to provide additional extension points

In order to use the Template Method, subclasses and application code will supply any abstract steps and optionally override any optional steps. This mechanism ensures that the overall operation or algorithm flow is enforced while granting users the ability to override specific details.

The mechanisms used to implement this pattern depend on the chosen language. Common choices include:

Consequences

The Template Method pattern eliminates duplication across implementations by keeping the common operational code in a single location. The pattern also gives the base implementation control over the general algorithm while giving clients the ability to customize specific implementation steps. This improves reusability of the code, as users can modify steps to suit the situation. The pattern can also be used to decouple the operation from a specific hardware or software platform, since implementation details can be supplied through abstract steps that the user is required to implement.

Template Methods make use of Inversion of Control – the “lower-level” code (the library, framework, or base class) invokes “higher-level” code (an application or subclass). While useful, this can make the processing flow difficult to trace for those not familiar with the software, as some implementation details in the higher-level code will appear to be present but not used by the application. When debugging, this can lead to a “ping pong” or “yo yo” effect, where you are tracing back-and-forth between the code that defines the Template Method and the code that implements individual steps.

Users must be able to identify which operations they are required to implement (“abstract operations”) and which are optional. This is best addressed in the interface documentation. Users can also be aided by using a naming convention to help identify optional and required steps to implement. Failure to document these details reduces the likelihood that the code will be reused.

Gamma et al. point out (and we agree) that an important design goal when using Template Methods is to minimize the number of operations that a user must implement. The more operations that need to be overridden, the more tedious it is to use the code. Note that this is different from giving users the option to override specific steps that have a default implementation.

Known Uses

  • This pattern is fundamental and is often used by abstract class hierarchies, libraries, frameworks, and SDKs to provide customization of default behavior or to provide methods that must be implemented according to the specific use case.
  • Template Methods can be used to decouple software from external dependencies, such as specific hardware components or operating systems. Users can supply platform-specific implementation details through template methods, allowing the original code to be decoupled from any particular platform.
  • Template Methods are often used within generated code to allow users to customize behavior without needing to directly modify the generated code. This is often called the Generation Gap pattern.
  • Template Method can be used to refactor classes or functions with a significant amount of code duplication, but variation in individual steps. Martin Fowler captures this process in the Form Template Method refactoring pattern.
    1. Identify the differences in the existing code.
    2. Separate the differences into new operations.
    3. Replace the differing code with a Template Method that calls the new operations.

Examples

Variants

  • The Generation Gap pattern is a specialization of the Template Method pattern to ensure users do not directly modify generated code.
  • Factory Methods can be viewed as a specialization of the Template Method pattern.
  • The Non-Virtual Interface (NVI) Pattern is a way to implement the Template Method pattern
  • The Strategy Pattern can be viewed a larger-scale extension of the ideas behind the Template Method: Strategy varies an algorithm in its entirety, where Template Method is used to vary individual steps of an algorithm while enforcing an overall algorithm structure.
    • Others distinguish these two patterns by saying that Template Method uses inheritance while Strategy uses delegation (delegating the algorithm to another section of code). We find this particular distinction as artificially limiting, since the idea behind Template Method can be applied even without inheritance.
  • Factory Methods and Template Methods can often be found together, with a Factory Method being used as a step within a larger Template Method.
  • Callback Functions operate similarly to the Template Method Pattern. For both patterns, tight coupling between modules can be handled externally by supplying an implementation for an optional customizable step. Callback operations are conceptually focused on customizing what happens when an operation is completed or event occurs, whereas the Template Method pattern is conceptually focused on customizing what happens during an operation. Given this, callbacks can be viewed as an application of Template Method.
  • Martin Fowler describes a Form Template Method refactoring pattern. When you notice that two related methods perform similar steps in the same order, yet the steps are different, you can refactor to a Template Method pattern.
    • Gamma et al. describe refactoring using Template Method as well.

References

Template_method_pattern (Wikipedia)

In object-oriented programming, the template method is one of the behavioral design patterns identified by Gamma et al. in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method.

The helper methods may be either abstract methods, in which case subclasses are required to provide concrete implementations, or hook methods, which have empty bodies in the superclass. Subclasses can (but are not required to) customize the operation by overriding the hook methods. The intent of the template method is to define the overall structure of the operation, while allowing subclasses to refine, or redefine, certain steps.

Synonyms:
Template Method
Categories: Field Atlas


« Back to Glossary Index

Share Your Thoughts

This site uses Akismet to reduce spam. Learn how your comment data is processed.