© Vaskaran Sarcar 2020
V. SarcarDesign Patterns in C#https://doi.org/10.1007/978-1-4842-6062-3_16

16. Template Method Pattern

Vaskaran Sarcar1 
(1)
Garia, Kolkata, West Bengal, 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

Using this pattern, you begin with the minimum or essential structure of an algorithm. Then you defer some responsibilities to the subclasses. As a result, the derived class can redefine some steps of an algorithm without changing the flow of the algorithm.

Simply, this design pattern is useful when you implement a multistep algorithm but allow customization through subclasses.

Real-World Example

When you order a pizza, the chef of the restaurant can use a basic mechanism to prepare the pizza, but he may allow you to select the final materials. For example, a customer can opt for different toppings such as bacon, onions, extra cheese, mushrooms, and so on. So, just before the delivery of the pizza, the chef can include these choices.

Computer-World Example

Suppose that you have been hired to design an online engineering degree course. You know that, in general, the first semester of the course is the same for all courses. For subsequent semesters, you need to add new papers or subjects to the application based on the course opted by a student.

The Template Method pattern makes sense when you want to avoid duplicate code in your application but allow subclasses to change some specific details of the base class workflow to bring varying behavior to the application. (However, you may not want to override the base methods entirely to make radical changes in the subclasses. In this way, the pattern differs from simple polymorphism.)

Implementation

Assume that each engineering student needs to pass mathematics and demonstrate soft skills (such as communication skills, people management skills, and so on) in their initial semesters to obtain their degrees. Later, you add special papers to their courses based on their chosen paths (computer science or electronics).

To serve the purpose, a template method DisplayCourseStructure() is defined in an abstract class BasicEngineering, which is as follows.
    /// <summary>
    /// Basic skeleton of actions/steps
    /// </summary>
    public abstract class BasicEngineering
    {
        //The following method(step) will NOT vary
        private void Math()
        {
            Console.WriteLine("1.Mathematics");
        }
        //The following method(step) will NOT vary
        private  void SoftSkills()
        {
            Console.WriteLine("2.SoftSkills");
        }
        /*
        The following method will vary.It will be
        overridden by derived classes.
        */
        public abstract void SpecialPaper();
        //The "Template Method"
        public void DisplayCourseStructure()
        {
            //Common Papers:
            Math();
            SoftSkills();
            //Specialized Paper:
            SpecialPaper();
        }
    }

Note that subclasses of BasicEngineering cannot alter the flow of DisplayCourseStructure() method , but they can override the SpecialPaper() method to include course-specific details and make the final course list different from each other.

The concrete classes called ComputerScience and Electronics are the subclasses of BasicEngineering, and they take the opportunity to override the SpecialPaper() method . The following code segment shows such a sample from the ComputerScience class .
//The concrete derived class-ComputerScience
public class ComputerScience : BasicEngineering
{
  public override void SpecialPaper()
  {
        Console.WriteLine("3.Object-Oriented Programming");
  }
}

Class Diagram

Figure 16-1 shows the important parts of the class diagram.
../images/463942_2_En_16_Chapter/463942_2_En_16_Fig1_HTML.jpg
Figure 16-1

Class diagram

Solution Explorer View

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

Solution Explorer view

Demonstration 1

Here’s the implementation.
using System;
namespace TemplateMethodPattern
{
    /// <summary>
    /// Basic skeleton of actions/steps
    /// </summary>
    public abstract class BasicEngineering
    {
        //The following method(step) will NOT vary
        private void Math()
        {
            Console.WriteLine("1.Mathematics");
        }
        //The following method(step) will NOT vary
        private  void SoftSkills()
        {
            Console.WriteLine("2.SoftSkills");
        }
        /*
        The following method will vary.It will be
        overridden by derived classes.
        */
        public abstract void SpecialPaper();
        //The "Template Method"
        public void DisplayCourseStructure()
        {
            //Common Papers:
            Math();
            SoftSkills();
            //Specialized Paper:
            SpecialPaper();
        }
    }
    //The concrete derived class-ComputerScience
    public class ComputerScience : BasicEngineering
    {
        public override void SpecialPaper()
        {
            Console.WriteLine("3.Object-Oriented Programming");
        }
    }
    //The concrete derived class-Electronics
    public class Electronics : BasicEngineering
    {
        public override void SpecialPaper()
        {
            Console.WriteLine("3.Digital Logic and Circuit Theory");
        }
    }
    //Client code
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***Template Method Pattern Demonstration-1.*** ");
            BasicEngineering bs = new ComputerScience();
            Console.WriteLine("Computer Science course includes the following subjects:");
            bs.DisplayCourseStructure();
            Console.WriteLine();
            bs = new Electronics();
            Console.WriteLine("Electronics course includes the following subjects:");
            bs.DisplayCourseStructure();
            Console.ReadLine();
        }
    }
}

Output

Here’s the output.
***Template Method Pattern Demonstration-1.***
Computer Science course includes the following subjects:
1.Mathematics
2.SoftSkills
3.Object-Oriented Programming
Electronics course includes the following subjects:
1.Mathematics
2.SoftSkills
3.Digital Logic and Circuit Theory

Q&A Session

16.1 In this pattern, subclasses can simply redefine the methods based on their needs. Is this correct?

Yes.

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

This is a simple example with only three methods, and you want the subclasses to override only the SpecialPaper() method here. Other methods are common to both courses, and they do not need to be overridden by the subclasses.

16.3 Suppose that you want to add some more methods in the BasicEngineering class, but you want to work on those methods if and only if your child classes need them; otherwise, you ignore them. This type of situation is common in some PhD programs where some courses are mandatory, but if a student has certain qualifications, the student may not need to attend the lectures for those subjects. Can you design this kind of situation with the Template Method pattern?

Yes, you can. Basically, you want to use a hook, which is a method that can help you to control the flow in an algorithm.

To show an example of this kind of design, now I add one more method in BasicEngineering called IncludeAdditionalPaper() . Let’s assume that by default, this subject is included in the course list, but electronics students can opt-out of this course.

The modified BasicEngineering class now looks like the following (note the bold lines that indicate the important changes).
    /// <summary>
    /// Basic skeleton of actions/steps
    /// </summary>
    public abstract class BasicEngineering
    {
        //The following method(step) will NOT vary
        private void Math()
        {
            Console.WriteLine("1.Mathematics");
        }
        //The following method(step) will NOT vary
        private void SoftSkills()
        {
            Console.WriteLine("2.SoftSkills");
        }
        /*
        The following method will vary.It will be
        overridden by derived classes.
        */
        public abstract void SpecialPaper();
        //The "Template Method"
        public void DisplayCourseStructure()
        {
            //Common Papers:
            Math();
            SoftSkills();
            //Specialized Paper:
            SpecialPaper();
            //Include an additional subject if required.
            if (IsAdditionalPaperNeeded())
            {
                IncludeAdditionalPaper();
            }
        }
        private void IncludeAdditionalPaper()
        {
            Console.WriteLine("4.Compiler Design.");
        }
        //A hook method.
        //By default,an additional subject is needed
        public virtual bool IsAdditionalPaperNeeded()
        {
            return true;
        }
    }
Since Electronics class doesn’t need to include the additional method, it is defined as follows:
    //The concrete derived class-Electronics
    public class Electronics : BasicEngineering
    {
        public override void SpecialPaper()
        {
            Console.WriteLine("3.Digital Logic and Circuit Theory");
        }
        //Using the hook method now.
        //Additional paper is not needed for Electronics.
        public override bool IsAdditionalPaperNeeded()
        {
            return false;
        }
    }

Let’s go through the program and output now.

Demonstration 2

Here’s the modified implementation. The key changes are shown in bold.
using System;
namespace TemplateMethodPattern
{
    /// <summary>
    /// Basic skeleton of actions/steps
    /// </summary>
    public abstract class BasicEngineering
    {
        //The following method(step) will NOT vary
        private void Math()
        {
            Console.WriteLine("1.Mathematics");
        }
        //The following method(step) will NOT vary
        private void SoftSkills()
        {
            Console.WriteLine("2.SoftSkills");
        }
        /*
        The following method will vary.It will be
        overridden by derived classes.
        */
        public abstract void SpecialPaper();
        //The "Template Method"
        public void DisplayCourseStructure()
        {
            //Common Papers:
            Math();
            SoftSkills();
            //Specialized Paper:
            SpecialPaper();
            //Include an additional subject if required.
            if (IsAdditionalPaperNeeded())
            {
                IncludeAdditionalPaper();
            }
        }
        private void IncludeAdditionalPaper()
        {
            Console.WriteLine("4.Compiler Design.");
        }
        //A hook method.
        //By default,an additional subject is needed.
        public virtual bool IsAdditionalPaperNeeded()
        {
            return true;
        }
    }
    //The concrete derived class-ComputerScience
    public class ComputerScience : BasicEngineering
    {
        public override void SpecialPaper()
        {
            Console.WriteLine("3.Object-Oriented Programming");
        }
        //Not tested the hook method.
        //An additional subject is needed
    }
    //The concrete derived class-Electronics
    public class Electronics : BasicEngineering
    {
        public override void SpecialPaper()
        {
            Console.WriteLine("3.Digital Logic and Circuit Theory");
        }
        //Using the hook method now.
        //Additional paper is not needed for Electronics.
        public override bool IsAdditionalPaperNeeded()
        {
            return false;
        }
    }
    //Client code
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***Template Method Pattern Demonstration-2.*** ");
            BasicEngineering bs = new ComputerScience();
            Console.WriteLine("Computer Science course includes the following subjects:");
            bs.DisplayCourseStructure();
            Console.WriteLine();
            bs = new Electronics();
            Console.WriteLine("Electronics course includes the following subjects:");
            bs.DisplayCourseStructure();
            Console.ReadLine();
        }
    }
}

Output

Here’s the modified output.
***Template Method Pattern Demonstration-2.***
Computer Science course includes the following subjects:
1.Mathematics
2.SoftSkills
3.Object-Oriented Programming
4.Compiler Design.
Electronics course includes the following subjects:
1.Mathematics
2.SoftSkills
3.Digital Logic and Circuit Theory
Note

You may prefer an alternative approach. For example, you could directly include the default method called IncludeAdditionalPaper() in BasicEngineering. After that, you could override the method in the Electronics class and make the method body empty. But this approach does not look better when you compare it to the previous approach.

16.4 It looks like this pattern is similar to the Builder pattern. Is this correct?

No. Don’t forget the core intent; the Template Method pattern is a behavioral design pattern, and Builder is a creational design pattern. In the Builder pattern, the clients/customers are the bosses. They can control the order of the algorithm. In the Template Method pattern, you (or the developers) are the boss. You put your code in a central location (for example, the abstract class BasicEngineering.cs in this example), and you have absolute control over the flow of the execution, which cannot be altered by the client. For example, you can see that Mathematics and SoftSkills always appear at the top, following the execution order in the template method DisplayCourseStructure(). The clients need to obey this flow.

If you alter the flow in your template method, other participants will also follow the new flow.

16.5 What are the key advantages of using a Template Method design pattern?

Here are some of the key advantages.
  • You can control the flow of the algorithms. Clients cannot change them.

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

16.6 What are the key challenges associated with a Template Method design pattern?

The disadvantages can be summarized as follows.
  • The client code cannot direct the sequence of steps. If you want that type of functionality, use the Builder pattern.

  • A subclass can override a method defined in the parent class

    (in other words, hiding the original definition in the parent class), which can go against the Liskov substitution principle that basically says that if S is a subtype of T, then objects of type T can be replaced with objects of type S.

  • Having more subclasses means more scattered code and difficult maintenance.

16.7 What happens if a subclass tries to override the other parent methods in BasicEngineering?

This pattern suggests not to do that. When you use this pattern, you should not override all the parent methods entirely to bring a radical change in the subclasses. In this way, it differs from simple polymorphism.

16.8 How does this pattern differ from the Strategy pattern ?

You have identified a good point. Yes, the Strategy and the Template Method patterns have similarities. In Strategy, you can vary the entire algorithm using delegation; however, the Template Method pattern suggests that you vary certain steps in an algorithm using inheritance, but the overall flow of the algorithm is unchanged.

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

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