© Vaskaran Sarcar 2019
Vaskaran SarcarJava Design Patternshttps://doi.org/10.1007/978-1-4842-4078-6_16

16. Template Method Pattern

Vaskaran Sarcar1 
(1)
Bangalore, Karnataka, India
 

This chapter covers the Template Method pattern.

GoF Definition

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.

Concept

In a template method, you define the minimum or essential structure of an algorithm. Then you defer some responsibilities to the subclasses. The key intent is that you can redefine certain steps of an algorithm, but those changes should not impact the basic flow of the algorithm.

So, this design pattern is useful when you implement a multistep algorithm and you want to allow customization through subclasses.

Real-World Example

Suppose that you are ordering a pizza from a restaurant. For the chef, the basic preparation of the pizza is the same; he includes some final toppings based on customer choice. For example, you can opt for a veggie pizza or a non-veggie pizza. You can also choose toppings like bacons, onions, extra cheese, mushrooms, and so forth. The chef prepares the final product according to your preferences.

Computer-World Example

Suppose that you are making a program to design engineering courses. Let’s assume that the first semester is common for all streams. In subsequent semesters, you need to add new papers/subjects to the application based on the course. You see a similar situation in the upcoming illustration. Remember that this pattern makes sense when you want to avoid duplicate codes in your application. At the same time, you may want to allow subclasses to change some specific details of the base class workflow to provide varying behaviors in the application.

Note

The removeAll() method of java.util.AbstractSet is an example of the template method pattern. Apart from this, there are many non-abstract methods in java.util.AbstractMap and java.util.AbstractSet classes, which can also be considered as the examples of the template method pattern.

Illustration

In the following implementation, I assume that each engineering student needs to complete the course of Mathematics and then Soft skills (This subject may deal with communication skills, character traits, people management skills etc.) in their initial semesters to obtain the degree. Later you will add special paper/s to these courses (Computer Science or Electronics).

To serve the purpose, a method completeCourse() is defined in an abstract class BasicEngineering. I have also marked the method final, so that subclasses of BasicEngineering cannot override the completeCourse() method to alter the sequence of course completion order.

Two other concrete classes- ComputerScience and Electronics are the subclasses of BasicEngineering class and they are completing the abstract method completeSpecialPaper() as per their needs.

Class Diagram

Figure 16-1 shows the class diagram.
../images/395506_2_En_16_Chapter/395506_2_En_16_Fig1_HTML.jpg
Figure 16-1

Class diagram

Package Explorer View

Figure 16-2 shows the high-level structure of the program.
../images/395506_2_En_16_Chapter/395506_2_En_16_Fig2_HTML.jpg
Figure 16-2

Package Explorer View

Implementation

Here’s the implementation:
package jdp2e.templatemethod.demo;
abstract class BasicEngineering
{
    //Making the method final to prevent overriding.
    public final void completeCourse()
    {
        //The course needs to be completed in the following sequence
        //1.Math-2.SoftSkills-3.Special Paper
        //Common Papers:
        completeMath();
        completeSoftSkills();
        //Specialization Paper:
        completeSpecialPaper();
    }
    private void completeMath()
    {
        System.out.println("1.Mathematics");
    }
    private void completeSoftSkills()
    {
        System.out.println("2.SoftSkills");
    }
    public abstract void completeSpecialPaper();
}
class ComputerScience extends BasicEngineering
{
    @Override
    public void completeSpecialPaper() {
        System.out.println("3.Object-Oriented Programming");
    }
}
class Electronics extends BasicEngineering
{
    @Override
    public void completeSpecialPaper()
    {
        System.out.println("3.Digital Logic and Circuit Theory");
    }
}
public class TemplateMethodPatternExample {
    public static void main(String[] args) {
        System.out.println("***Template Method Pattern Demo*** ");
        BasicEngineering preferrredCourse = new ComputerScience();
        System.out.println("Computer Sc. course will be completed in following order:");
        preferrredCourse.completeCourse();
        System.out.println();
        preferrredCourse = new Electronics();
        System.out.println("Electronics course will be completed in following order:");
        preferrredCourse.completeCourse();
    }
}

Output

Here’s the output:
***Template Method Pattern Demo***
Computer Sc. course will be completed in following order:
1.Mathematics
2.SoftSkills
3.Object-Oriented Programming
Electronics course will be completed in following order:
1.Mathematics
2.SoftSkills
3.Digital Logic and Circuit Theory

Q&A Session

  1. 1.

    In this pattern, I am seeing that subclasses can simply redefine the methods as per their need. Is the understanding correct?

    Yes.

     
  2. 2.

    In the abstract class BasicEngineering, only one method is abstract, other two methods are concrete methods. What is the reason behind it?

    It is a simple example with only 3 methods where I wanted the subclasses to override only the completeSpecialPaper() method . Other methods are common to both stream and they do not need to be overridden by the subclasses.

     
  3. 3.

    Consider a situation like this: Suppose you want to add some more methods in the BasicEngineering class but you want to work on those methods if and only if, the child classes need them otherwise you will ignore them. This type of situation is very common in some PhD courses where some courses are not mandatory for all candidates. For example, if a student has certain qualifications, he/she may not need to attend the lectures of those subjects. Can you design this kind of situation with the Template Method Pattern?

    Yes, we can. Basically, you may need to put a hook which is nothing but a method that can help us to control the flow in an algorithm.

    To show an example of this kind of design, I am adding one more method in BasicEngineering called is AdditionalPapersNeeded() . Let us assume that Computer science students need to complete this course, but Electronics students can opt out this paper. Let’s go through the program and output.

     

Modified Implementation

Here’s the modified implementation. Key changes are shown in bold.
package jdp2e.templatemethod.questions_answers;
abstract class BasicEngineering
{
    //Making the method final to prevent overriding.
    public final void completeCourse()
    {
        //The course needs to be completed in the following sequence
        //1.Math-2.SoftSkills-3.Special Paper-4.Additional Papers(if any)
        //Common Papers:
        completeMath();
        completeSoftSkills();
        //Specialization Paper:
        completeSpecialPaper();
        if (isAdditionalPapersNeeded())
        {
            completeAdditionalPapers();
        }
    }
    private void completeMath()
    {
        System.out.println("1.Mathematics");
    }
    private void completeSoftSkills()
    {
        System.out.println("2.SoftSkills");
    }
    public abstract void completeSpecialPaper();
    private void completeAdditionalPapers()
    {
        System.out.println("4.Additional Papers are needed for this course.");
    }
    //By default, AdditionalPapers are needed for a course .
    boolean isAdditionalPapersNeeded()
    {
        return true;
    }
}
class ComputerScience extends BasicEngineering
{
    @Override
    public void completeSpecialPaper()
    {
        System.out.println("3.Object-Oriented Programming");
    }
    //Additional papers are needed for ComputerScience
    //So, there is no change for the hook method.
}
class Electronics extends BasicEngineering
{
    @Override
    public void completeSpecialPaper()
    {
        System.out.println("3.Digital Logic and Circuit Theory");
    }
    //Overriding the hook method:
    //Indicating that AdditionalPapers are not needed for Electronics.
    @Override
    public  boolean isAdditionalPapersNeeded()
    {
        return false;
    }
}
public class TemplateMethodPatternModifiedExample {
    public static void main(String[] args) {
        System.out.println("***Template Method Pattern Modified Demo*** ");
        BasicEngineering preferrredCourse = new ComputerScience();
        System.out.println("Computer Sc. course will be completed in following order:");
        preferrredCourse.completeCourse();
        System.out.println();
        preferrredCourse = new Electronics();
        System.out.println("Electronics course will be completed in following order:");
        preferrredCourse.completeCourse();
    }
}

Modified Output

Here’s the modified output:
***Template Method Pattern Modified Demo***
Computer Sc. course will be completed in following order:
1.Mathematics
2.SoftSkills
3.Object-Oriented Programming
4.Additional Papers are needed for this course.
Electronics course will be completed in following order:
1.Mathematics
2.SoftSkills
3.Digital Logic and Circuit Theory

Note

You may prefer an alternative approach. For example, you could make a default method isAdditionalPapersNeeded() in BasicEngineering. Then you could override the method in Electronics class and then you could make the method body empty. But this approach does not look better if you compare it to the previous approach.

  1. 4.

    Looks like this pattern is similar to Builder pattern.Is the understanding correct ?

    No. You should not forget the core intent;Template Method is a behavioral design patterns, and Builder is a creational design pattern. In Builder Patterns, the clients/customers are the boss-they can control the order of the algorithm. On the other hand, in Template Method pattern, you are the boss-you put your code in a central location and you only provide the corresponding behavior (For example, notice the completeCourse() method in BasicEngineering and see how the course completion order is defined there).So, you have absolute control over the flow of the execution. You can also alter your template as per your need and then other participants need to follow you.

     
  2. 5.

    What are the key advantages of using a template design pattern?

    • You can control the flow of the algorithms. Clients cannot change them. (Notice that completeCourse() is marked with final keyword in the abstract class BasicEngineering)

    • Common operations are placed in a centralized location, for example, in an abstract class. The subclasses can redefine only the varying parts, so that, you can avoid redundant codes.

     
  3. 6.

    What are key challenges associated with a template design pattern?

    • Client code cannot direct the sequence of steps (If you need that approach, you may follow the Builder pattern).

    • A subclass can override a method defined in the parent class (i.e. hiding the original definition in parent class) which can go against Liskov Substitution Principle that basically says: If S is a subtype of T, then objects of type T can be replaced with objects of type S. You can learn the details from the following link: https://en.wikipedia.org/wiki/Liskov_substitution_principle

    • More subclass means more scattered codes and difficult maintenance.

     
  4. 7.

    Looks like the subclasses can override other parent methods also in the BasicEngineering. Is the understanding correct?

    You can do this but ideally that should not be your intent. In this pattern, you may not want to override all the parent methods entirely to bring the radical changes in the subclasses. In this way, it differs from simple polymorphism.

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.189.186