Template Method Design Pattern

abh1navv

Abhinav Pandey

Posted on February 22, 2022

Template Method Design Pattern

Template method pattern is a design pattern that allows you to define a skeleton of an algorithm in an operation, deferring some steps to subclasses.

In simpler terms, this is like making a to-do list which multiple implementations follow in their own way.

Let's start with some terminology:

  1. Template Method - A template method is a method that defines the skeleton of an algorithm in an operation.
  2. Concrete Template - A concrete template is a class that implements the template method.
  3. Client - A client is a class that tells the template method which concrete template to use.
  4. Abstract Steps - An abstract step is a method that is defined in the template method but is left to be implemented by the subclasses.

A real world example

Let's think about an example of this in the real world. We will compare this to a digital payment system.

  • The payment system has a payment gateway which is a template method.
  • The customer can use the payment gateway to make a payment.
  • The payment gateway has a few steps that are defined in the template method - validating the payment, transferring the money and updating the database.
  • However, the implementation of these steps is decided by the exact payment option that the customer chooses - Credit Card, Net Banking, PayPal, etc.

Let's code this up

The Template Method

Let's create an abstract class called PaymentGateway:

public abstract class PaymentGateway {
    public final void makePayment() {
        validatePayment();
        transferMoney();
        updateDatabase();
    }
    protected abstract void validatePayment();
   protected abstract void transferMoney();
   protected abstract void updateDatabase();
}
Enter fullscreen mode Exit fullscreen mode

Here we have a template method makePayment() which calls the three steps of the payment process. None of the steps are implemented in the abstract class.
This method defines a template that its subclasses must follow to make a payment.

We could also have provided a default implementation of the steps in the abstract class for reusability but this is an implementation decision.

To make it even more strict, we have made the template method final so that it cannot be overridden. It is a good practice to make the template method final, but it is not a requirement.

The Concrete Templates

Let's create concrete templates for the payment gateway. We will create two concrete templates:

  1. CreditCardPaymentGateway - This template will implement the steps of the payment process for credit card payments.
  2. PayPalPaymentGateway - This template will implement the steps of the payment process for PayPal payments.
public class CreditCardPaymentGateway extends PaymentGateway {
    public void validatePayment() {
        // check if the credit card is valid
        // check if the credit card has sufficient balance
        // check if the credit card is expired
    }
    public void transferMoney() {
        // transfer the money from the credit card to the bank account
    }
    public void updateDatabase() {
        // update the database with the transaction details
    }
}
Enter fullscreen mode Exit fullscreen mode
public class PayPalPaymentGateway extends PaymentGateway {
    public void validatePayment() {
        // check if the PayPal account is valid
        // check if the PayPal account has sufficient balance
    }
    public void transferMoney() {
        // transfer the money from the PayPal account to the bank account
    }
    public void updateDatabase() {
        // update the database with the transaction details
    }
}
Enter fullscreen mode Exit fullscreen mode

The Client

To choose the payment gateway, we could use a factory. In our case, the factory will return the appropriate payment gateway based on the customer's payment option.

public class PaymentGatewayFactory {
    public PaymentGateway getPaymentGateway(String paymentOption) {
        if (paymentOption.equals("credit card")) {
            return new CreditCardPaymentGateway();
        } else if (paymentOption.equals("paypal")) {
            return new PayPalPaymentGateway();
        } else {
            throw new IllegalArgumentException("Invalid payment option");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The client will use the factory to get the appropriate payment gateway and make the payment.

public class PaymentGatewayClient {
    public static void main(String[] args) {
        PaymentGatewayFactory factory = new PaymentGatewayFactory();
        PaymentGateway gateway = factory.getPaymentGateway("credit card");
        gateway.makePayment();
    }
}
Enter fullscreen mode Exit fullscreen mode

When the makePayment method is called on the payment gateway, the template method defined in the abstract class is called.
However, the concrete methods of CreditCardPaymentGateway are called to execute the internal steps.

Advantages of the Template Method

  1. It provides a flexible way to change the implementation of internal steps without missing any of the steps.
  2. It provides a flexible way to add more implementations in the future.

Template method pattern is used in Java for many out-of-the-box implementations. For example, InputStreamReader is a template method pattern implementation.


Thanks for reading! This should help you understand the concept of the template method pattern. Stay tuned for more design patterns.
If you want to connect with me, you can find me on Twitter @abh1navv

💖 💪 🙅 🚩
abh1navv
Abhinav Pandey

Posted on February 22, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Template Method Design Pattern
java Template Method Design Pattern

February 22, 2022