Used to manage and execute different functions for different objects, where functions share some common code

The Template Pattern is implemented to perform different behaviors represented from context object using the template object(s).

It is what is being currently used in a lot of places, substituting the State Pattern to follow the modern practice of decentralization of state into smaller components for a more robust component architecture in most frameworks like React JS, Next JS etc.‌
‌In fact, React JS Hooks, which got introduced in 2016 and took the component driven framework world by a storm, implement the Template Model and Strategy Pattern logic under the hood !

Feel free to browse through this detailed blog on Strategy Pattern for reference  :‌

Strategy Pattern
Learning the OOP way to execute different algorithms in different situations using the Strategy Pattern

Template Model Pattern is like a version of strategy pattern where the implementation is done through a parent abtract class instead of an interface to give the 2 options to the child classes -

  1. Polymorph the required methods
  2. Inherit the required methods right from how the parent defines them

Ok, but what is Polymorphing ?

Polymorphism is one of the fundamentals of Object Oriented Programming. What it lays down is this -

"Child classes extending an abstract parent class have to implement the methods (functions) prescribed by the parent class.
This is other done by inheriting i.e. copying the method implementation from the parent, or by coming up with their own implementation of the same method (aka polymorphing), which shall override the parent's implementaion."

meme


Yeah sure, but what exactly is an abstract parent class ?

In polymorphism, we use the concept of an abstract parent class where the parent class just provides a base template with some variables and functions defined
Child classes extending this template can either inherit this template's definitions or come up with their own custom implementations of the methods, variables declared in the template (aka polymorphing the methods, variables).

Salient features :

  1. Abstract parent classes can't be instantiated (can't make objects directly from these classes)
  2. Any abstract class that contains abstract methods, concrete methods (methods that can't be polymorphed) or both
  3. Any class which extends this abstract class must override the abstract methods.
  4. Abstract methods can be declared only in abstract classes.

meme


So how is this any different from the Strategy Pattern ?

So how is this any different from the State Pattern ?


STRATEGY PATTERN TEMPLATE MODEL PATTERN
The base layer is an interface The base layer is a parent abstract class
Child classes compulsorily have to implement all the logic declared in the base layer themselves Child classes have the flexibility to either implement all the logic declared in the base layer themselves (polymorphing) or simple inherit it from the parent

concept

Resources

The source code for all prominent design patterns has been properly implemented and documented in this GitHub repostitory by me.‌‌

crew-guy/Design-Patterns
A collection of the design patterns, implemented in java, as originally created by the GoF - crew-guy/Design-Patterns

Project Description

Here, in this article, we will be building a simple application that mimics digital transaction processing like any payments gateway like Google Pay, PayTM or any bank in the sense that we will layout the structure of how an audit trail is implemented by classes for transfering money and generating reports 🔥‌‌

app

Setting up the Context

This class simply generates our context object i.e. our audit trail for the task method to do some functions on

public class AuditTrail {
    public void record(){
        System.out.println("Audit recorded !");
    }
}

AuditTrail.java

Implementing the Template

A template is just common interface for exposing a multitude of functionalities offered by our software

It is implemented as an abstract parent class or as an interface in all OOP languages. It just has to enlist the methods that all classes extending it can polymorph or inherit in their own way for providing the - "same interface - different/same function" feature.‌‌‌‌

We have defined 1 template - Task (which will be our Template class), with the following abstract and concrete methods defined.


Method Name Method Type Function of Method
doExecute() abstract Prototype of method for implementing the logic of the audit task being executed (eg :generate a report, transfer money )
execute() concrete Fixed method for running some startup middleware processing irrespective of whichever audit task you wish to execute (eg: generate a report, transfer money)
public abstract class Task {
    public AuditTrail auditTrail;

    public Task(){
        this.auditTrail = new AuditTrail();
    }

    public Task(AuditTrail auditTrail){
        this.auditTrail = auditTrail;
    }

    public void execute(){
        auditTrail.record();
        System.out.println("Starting execution of transaction......");

        doExecute();
    }

    protected abstract void doExecute();
}
Task.java
  1. Here, the protected keyword is used to ensure that only the child classes extending this class can access this method and no one else.
    It gives a sort of role based access control to our doExecute( ) method.
  2. Also, as visible here, the execute( ) method is what is called on each task to do 2 things
    - First, run some middleware that starts the transaction and records it
    -  Run the task i.e. the crux of this transaction

Implementing the Concrete classes

Child classes that extend their respective Template class and implement the abstracted prototype methods listed by the interface ‌that they extend

Concrete Class Name Function
MoneyTransfer Implementation of the logic for transferring money will exist here
GenerateReport Implementation of the logic generating a report will exist here
public class TransferMoneyTask extends Task{
    @Override
    protected void doExecute() {
        System.out.println("Your money has been successfully transferred !");
    }
}
MoneyTransfer.java
public class GenerateReportTask extends Task{
    @Override
    protected void doExecute() {
        System.out.println("Your report has been successfully generated !");
    }
}
GenerateReport.java

Using this pattern in our application

Import all the necessary classes and modules into main.java for a final showdown of our application ! Here, I'll be running both tasks just to show how some common code as well as some unique code, will run for both these tasks ‌

var task = new TransferMoneyTask();
task.execute();
var task2 = new GenerateReportTask();
task.execute();
task2.execute();

Conclusion

Congrats on unlocked the secret of how most modern implementations of reactive applications work under the hood. You should feel pretty comfortable now developing the state responsive functionalities in a decentralized but structured manner in your applications. Until next time...‌‌

eye

References..

Whatever I have learnt and implemented here in code as well as the explanation is all from the teachings of the brilliant Mosh Hamedani and his course on Design Patterns which I would recommend you to take if you are really interested in exploring the beauty of Object Oriented Programming

The Ultimate Design Pattern Series
Ace your coding job interview. Learn to write maintainable and extensible code.