The template method design pattern allows you to define the steps of an algorithm within a single method of a class. This allows you to constrain specific operations of an application to a single method.

Each step of the algorithm that the template method defines is an inner method. However, the template method only handles the implementation of some of its inner methods. Subclasses usually implement one or more of the template method’s inner methods.

A subclass can implement an abstract method, but it can’t redefine the algorithm implemented by a final method.

How the Template Method Works

A typical template method pattern will have the following structure:

        final void templateMethod() {
    abstractOperation1();
    abstractOperation2();
 
    concreteOperation1();
    concreteOperation2();
 
    hook();
}

The first important thing to note is that templateMethod() is final, so no subclass can override this method. The other important thing to note is the three types of methods that the template method pattern uses: concrete, abstract, and hook.

The abstract class that houses the template method implements all its concrete methods, while concrete subclasses implement its abstract methods. The hook method usually does nothing by default, but a subclass does have the ability to override these methods when necessary.

Implementing the Template Method Pattern in Java

The template method pattern acts as a framework for an application. So, you’ll often see this pattern in software frameworks that provide the blueprint for application development.

For example, you can connect your application to one of many database systems. The steps to connect to and use a database follow a similar template:

        public abstract class Database {
    // template method
    final void databaseTemplate() {
        // abstract methods
        setDBDriver();
        setCredentials();
 
        // concrete method
        connect();
 
        // abstract methods
        createDB();
        setData();
        readData();
 
        // hook methods
        if (userWantsToUpdate()) {
            updateData();
        }
 
        if (userWantsToDelete()) {
            deleteData();
        }
 
        // concrete method
        closeConnection();
    }
 
    abstract void setDBDriver();
    abstract void setCredentials();
    abstract void createDB();
    abstract void setData();
    abstract void readData();
    abstract void updateData();
    abstract void deleteData();
 
    void connect() {
        System.out.println("Connecting to database...");
    }
 
    void closeConnection() {
        System.out.println("Destroying database connection...");
    }
 
    boolean userWantsToUpdate() {
        return false;
    }
 
    boolean userWantsToDelete() {
        return false;
    }
}

This example Database class uses the template method pattern to create a template that you can use with any database. To use a database, your application will need to connect to it, then destroy the connection after use. These activities are usually the same for all databases. Therefore, the abstract Database class can implement the connect() and closeConnection() methods.

The other methods in the template method will differ based on the type of database. For example, a MySQL database stores data in tables, while a MongoDB database stores data in collections. If you want to use a MySQL database in Java, simply create a new MySQL class that extends the Database class:

        public class MySQL extends Database {
    @Override
    void setDBDriver() {
        System.out.println("Selecting MySQL driver...");
    }
 
    @Override
    void setCredentials() {
        System.out.println("Setting MySQL database Credential...");
    }
 
    @Override
    void createDB() {
        System.out.println("Creating a new table...");
    }
 
    @Override
    void setData() {
        System.out.println("Inserting data into database...");
    }
 
    @Override
    void readData() {
        System.out.println("Retrieving data from database...");
    }
 
    @Override
    void updateData() {
        System.out.println("Updating data in database...");
    }
 
    @Override
    void deleteData() {
        System.out.println("Deleting data from database...");
    }
}

The MySQL class implements all the abstract methods of the Database class. It can also override some concrete methods. However, it cannot touch the databaseTemplate() method, which uses the final keyword.

        public class Main {
    public static void main(String[] args) {
        Database mySQLDB = new MySQL();
        mySQLDB.databaseTemplate();
    }
}

This Main class creates a new MySQL database object and uses the template method to simulate how an application would connect to the database. Running the main method prints the following output to the console:

MySQL database template method

In the output, you’ll notice that the application never calls the updateData() and deleteData() methods. This is why the hook methods are important. In an SQL database, you’ll want to create new tables, insert data, and view your data. However, you might not want to update or delete data. Therefore, the hook methods give subclasses the option to control these critical aspects of the algorithm.

        @Override
boolean userWantsToUpdate() {
    return true;
}

By simply adding the code above to the MySQL class, the application now updates the data in the database. If you run the Main class again it will display the following updated output:

MySQL database template method update

As you can see, the application is now updating the data in the Database.

The Benefits of Using the Template Method Design Pattern

A major benefit of the template method pattern is that it promotes software reusability. This design pattern also supports efficient programming. A subclass only needs to implement methods that are unique to its operation.

Additionally, an application that uses the template method pattern is more secure, as external classes cannot alter its operation structure.