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).
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.
Class Diagram
Solution Explorer View
Demonstration 1
Output
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.
Let’s go through the program and output now.
Demonstration 2
Output
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?
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 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.