TEMPLATE METHOD PATTERN

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

The Template Method pattern can be used in situations when there is an algorithm, some steps of which could be implemented in multiple different ways. In such scenarios, the Template Method pattern suggests keeping the outline of the algorithm in a separate method referred to as a template method inside a class, which may be referred to as a template class, leaving out the specific implementations of the variant portions (steps that can be implemented in multiple different ways) of the algorithm to different subclasses of this class.

The Template class does not necessarily have to leave the implementation to subclasses in its entirety. Instead, as part of providing the outline of the algorithm, the Template class can also provide some amount of implementation that can be considered as invariant across different implementations. It can even provide default implementation for the variant parts, if appropriate. Only specific details will be implemented inside different subclasses. This type of implementation eliminates the need for duplicate code, which means a minimum amount of code to be written.

  • Template method should consist of certain steps whose order is fixed and for some of the methods; implementation differs from base class to subclass. Template method should be final.
  • Most of the times, subclasses calls methods from super class but in template pattern, superclass template method calls methods from subclasses, this is known as Hollywood Principle – “don’t call us, we’ll call you.”
  • Methods in base class with default implementation are referred as Hooks and they are intended to be overridden by subclasses, if you want some of the methods to be not overridden, you can make them final, for example in our case we can make doPack () method final because if we don’t want subclasses to override it.

package com.myjavablog.behavioural.template;

public abstract class PurchaseOrderTemplate {

public abstract void doSelect();
public abstract void doPayment();
public final void doPack(){
System.out.println("Gift wrapping done.");
}
public abstract void doDelivery();
public final void processOrder(){
doSelect();
doPayment();
doPack();
doDelivery();
}

}

package com.myjavablog.behavioural.template;

public class StorePurchaseOrder extends PurchaseOrderTemplate{

@Override
public void doSelect() {
System.out.println("Customer selects item from shelf");
}

@Override
public void doPayment() {
System.out.println("Pay at counter through Cash/POS");
}

@Override
public void doDelivery() {
System.out.println("Item delivered to delivery counter");
}
}

package com.myjavablog.behavioural.template;

public class OnlinePurchaseOrder extends PurchaseOrderTemplate{

@Override
public void doSelect() {
System.out.println("Item added to online shopping cart");
System.out.println("Get gift wrap preference");
System.out.println("Get delivery address");
}

@Override
public void doPayment() {
System.out.println("Online Payment through Netbanking/Card");
}

@Override
public void doDelivery() {
System.out.println("Ship the item through post to delivery address");
}
}

 

package com.myjavablog.behavioural.template;

public class TemplateMethodPatternTest {

public static void main(String[] args) {

PurchaseOrderTemplate offline = new StorePurchaseOrder();
System.out.println("=======Shopping Offline========");
offline.processOrder();
PurchaseOrderTemplate online = new OnlinePurchaseOrder();
System.out.println("\n=======Shopping Online========");
online.processOrder();
}
}

 

Output:

=======Shopping Offline========
Customer selects item from shelf
Pay at counter through Cash/POS
Gift wrapping done.
Item delivered to delivery counter

=======Shopping Online========
Item added to online shopping cart
Get gift wrap preference
Get delivery address
Online Payment through Netbanking/Card
Gift wrapping done.
Ship the item through post to delivery address

When to use the Template Design Pattern:

  • To implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.
  • When common behavior among subclasses should be factored and localized in a common class to avoid code duplication. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.

Usage in JDK:

  • All non-abstract methods of java.io.InputStream, java.io.OutputStream, java.io.Reader and java.io.Writer. e.g. – java.io.InputStream#skip (), java.io.InputStream#read ()
  • All non-abstract methods of java.util.AbstractList, java.util.AbstractSet and java.util.AbstractMap. e.g. – java.util.AbstractList#indexOf (), java.util.Collections#sort ()

Leave a Comment

Bitnami