Tuesday, November 13, 2012

Template Method Design Pattern


Motivation:
At times different components have significant similarities with a only a few steps in between which might vary.  Let’s take few real time examples like buying a flight ticket online. We might buy the ticket from any website from anywhere most of the steps would be the same with some variations.
  •          Login to Website (We will have different websites).
  •          Selecting the itinerary for the journey
  •          Search the ticket (Different websites will offer different carriers).
  •          Apply the Offer (Offers will vary depending on the website).
  •          Select the ticket
  •          Payment

If we want to launch a new new website to book Air Tickets, Do I need to implement all these methods? How about if you get some default template implementation where you just need to plug few thing as per your requirements!!! Sounds interesting. Watch for the Template Method Pattern discussed below.

Definition:
Defines the skeleton of an algorithm in a method, deferring some steps to sub classes  Template Method lets sub classes redefine certain steps of an algorithm without changing the algorithms structure.

Structure:
The Template Method pattern is quite simple - let's look at a class diagram representation:



The AbstractClass contains the templateMethod(), which should be made final so that it cannot be overridden i.e. the order of the steps cannot be modified. This template method calls other operations available in order to run through the algorithm. Not all operations used by this template method need to be made abstract, we can have concrete methods with default implementation.

These concrete methods are that part of the algorithm which remains common. The ConcreteClass implements all the abstract operations required by the templateMethod in the parent class. There can be many different Concrete Class implementations. Abstract methods are that part of the algorithm which will vary.
Getting are Hands Dirty with Coding !!!
We will implement the above Flight Ticket booking Algorithm with help of Template Pattern.
  
public abstract class AirTicketBookingTemplate {
      public final void bookTicket() {
            loginToWebsite();
            chooseItenary();
            searchTicket();
            applyOffers();
            selectTheTicket();
            payment();
      }
      void chooseItenary() {
            System.out.println("Select Source/Destination/Date");
      }
      void displayingAllTicktes() {
            System.out.println("Displaying All the Availale Tickets!!");
      }
      void selectTheTicket() {
            System.out.println("You have selected the below Ticket!!");
      }
      void payment() {
            System.out.println("Payment Recieved !! Ticket Confimed.");
      }
      abstract void loginToWebsite();
      abstract void searchTicket();
      abstract void applyOffers();
}
This is the abstract class in which bookTicket act as a Template Method with some concrete and abstract methods.

Now let us have a look at our First Concrete Class:
public class MakeMyTrip extends AirTicketBookingTemplate{
      void loginToWebsite() {
            System.out.println("Welcome to www.makemytrip.com !!!");
      }
      void searchTicket() {
            System.out.println("Searching Jet Airways/Air India/Kingfisher/Indigo");
      }
      void applyOffers() {
            System.out.println("Current Offer is Buy one Ticket Get Another Free !!!");
      }
}
Another counterpart of MakeMyTrip which has really become popular these days is Goibibo. Let’s have a look and check how will they serve us. The booking algorithm or process is almost the same but it offers better Offers and gives us more number of choices to book the Ticket. Code is present below. 

public class GoIBiBo extends AirTicketBookingTemplate{
      void loginToWebsite() {
            System.out.println("Welcome to www.goibibo.com !!!");
      }
      void applyOffers() {
            System.out.println("Current Offer is Rs 200 off on one way 400 on return !!!");
      }
      void searchTicket() {
            System.out.println("Searching Sahara/Air India/Jet Lite/Go Air/SpiceJet/Jet Airways/Indigo");
      }
}
Oh…Finally I will be able to the book the Flight Ticket
public static void main(String[] args) {
      MakeMyTrip makeMyTrip = new MakeMyTrip();
      makeMyTrip.bookTicket();
      System.out.println("-------------------");
      GoIBiBo goIBiBo = new GoIBiBo();
      goIBiBo.bookTicket();
}
Output:
Welcome to www.makemytrip.com !!!
Select Source/Destination/Date
Searching Jet Airways/Air India/Kingfisher/Indigo
Current Offer is Buy one Ticket Get Another Free !!!
You have selected the below Ticket!!
Payment Recieved !! Ticket Confimed.
-------------------
Welcome to www.goibibo.com !!!
Select Source/Destination/Date
Searching Sahara/Air India/Jet Lite/Go Air/SpiceJet/Jet Airways/Indigo
Current Offer is Rs 200 off on one way 400 on return !!!
You have selected the below Ticket!!
Payment Recieved !! Ticket Confimed.
Getting Hooked with the Template
Hook is a method that is declared in abstract class, but only given empty or default implementation. This gives the subclasses the flexibility  to modify or hook into the algorithm at various points, if they wish. Subclasses are free to ignore the hook method if not required. 

Bigger Question here is when to use abstract method and when to use hooks?

Use abstract methods when your subclass must provide the implementation. Choose hook when it is optional for subclasses to implement it.
Let us understand Hooks inTemplate Design Pattern with a simple diagram below:
We will see how we can Hook in various features in our Daily Morning Walk.

We have placed two Hooks in our Morning Walk, one is to for Music lovers and other is for people who have house hold resposibilites as well. But let me tell you these are not mandatory. We can still enjoy our morning walk without any of these.
Let us know enhance our Flight Booking Example with some Hooks:
Here we have given a hook complimentaryMeal () which returns false by default  i.e. the no free meals will be served on the flight. But if a website prefers, it has all the right s to feed it’s hungry passengers for free.

public abstract class AirTicketBookingTemplate {
      public final void bookTicket() {
            //All the previous code here
            if(complimentaryMeal()){
                  chooseYourMeal();
            }
            payment();
      }
     
      abstract void chooseYourMeal();
      boolean complimentaryMeal(){
            return false;
      }
}

public class GoIBiBo extends AirTicketBookingTemplate{
      boolean complimentaryMeal() {
// This can also be based on Off Season or some Statistical Data to more profit
            return true;
      }    
      void chooseYourMeal() {
            System.out.println("Kindly Select the Complimentary Meal");
      }
}

Output:
All the lines are same as above only the highlighted part is different
Kindly Select the Complimentary Meal
Payment Recieved !! Ticket Confimed.

Hollywood Priciple:

The Template Method pattern makes use of the Hollywood Principle: Don't call us, we'll call you.  We will cover this topic in some other post.

When to Use Template Pattern?

 

·   When behavior of an algorithm can vary, you let sub classes implement the behavior through overriding
·       You want to avoid code duplication, implementing variations of the algorithm in sub classes
·         You want to control the point that subclassing is allowed.


2 comments: