- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Input Output Operations
- C++ Basic Input/Output
- C++ Cin
- C++ Cout
- C++ Manipulators
- Type System & Data Representation
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ Jump Statements
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Return Values
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Array Decay
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Destructors
- C++ Virtual Destructor
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Override Specifiers
- C++ Final Specifiers
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ Prototype Design Pattern
- C++ Structural Design Patterns
- C++ Facade Design Pattern
- C++ Iterator Design Pattern
- C++ Mediator Design Pattern
- C++ Memento Design Pattern
- C++ Observer Design Pattern
- C++ State Design Pattern
- C++ Strategy Design Pattern
- C++ Template Method Design Pattern
- C++ Visitor Design Pattern
- C++ Behavioural Design Pattern
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Move Semantics
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ nullptr
- C++ unordered_multiset
- C++ Chain of Responsibility
- C++ Structural Design Patterns
- C++ Adapter Pattern
- C++ Bridge Pattern
- C++ Composite Pattern
- C++ Decorator Pattern
- C++ Flyweight Pattern
- C++ Command Pattern
- C++ Proxy Pattern
Template Method Design Pattern in C++
The Template Method Design Pattern is a way to set up a common process that can be shared by different classes. It gives a main method called the template method that explains the steps to complete a task. Other classes can then fill in the details for some of those steps in their own way, without changing the main process. This helps in reusing code and keeping things simple as well as consistent.
This pattern is helpful when you have a task that follows the same steps every time, but a few steps might need to be done differently. You can keep the main steps in one place and let other classes change only the parts they need. This makes the program easy to read and simple to manage.
For example, think of a program that shows how to prepare a meal. The template method might describe the main steps : gathering ingredients, cooking, and serving. Now, other classes can change how these steps are done to make different meals like breakfast, lunch, or dinner. The main idea stays the same, but each meal can have its own special details.
Key Parts of the Template Method Design Pattern
The Template Method Design Pattern has following components that work together −
- The Abstract Class is the main class that defines the overall process. It includes the template method, which lists all the steps in order. Some steps may already have code, while others are left empty so other classes can fill them in later.
- The Template Method is the main method that shows how the task should be done from start to finish. It calls smaller methods for each step. Some of those smaller methods might be complete, and some might be waiting for other classes to finish them.
- The Concrete Subclasses are the classes that come from the abstract class. They complete the unfinished steps by adding their own code. Each subclass can do things a little differently, but they all still follow the main process written in the template method.
- The Hook Methods are optional steps that can be changed if needed. They let you add or skip small actions without touching the main process. Think of them like little switches you can turn on or off to change small parts of how things work.
C++ Implementation of the Template Method Design Pattern
Let's learn how to use the Template Method pattern in C++ with a simple example. We'll make a program that shows how to prepare different kinds of meals by following the same main steps.
Steps to use the Template Method pattern in C++
Following are the steps to implement the Template Method Design Pattern in C++
- First, make an abstract class that has one main method called the template method. This method lists all the steps of the process, like a recipe. Some steps will already have code, and others will be left empty so that other classes can fill them in later.
- Next, create subclasses that come from the abstract class. These classes will fill in the missing steps with their own code. For example, one class can show how to make breakfast, another one can show how to make lunch, and another one can show how to make dinner.
- Finally, use these subclasses to run the template method. The main steps stay the same, but each subclass adds its own little changes to make the meal special in its own way.
This way, you can keep the main process in one place and still make it easy to add new meal types later without changing the whole program.
C++ Code to Implement Template Method Design Pattern
Below is a simple C++ code example demonstrating the Template Method Design Pattern for preparing different types of meals.
#include <iostream>
using namespace std;
// Abstract class defining the template method
class Meal {
public:
// Template method
void prepareMeal() {
gatherIngredients();
cook();
serve();
}
// Abstract methods to be implemented by subclasses
virtual void gatherIngredients() = 0;
virtual void cook() = 0;
// Concrete method
void serve() {
cout << "Serving the meal!" << endl;
}
};
// Concrete subclass for preparing a breakfast meal
class Breakfast : public Meal {
public:
void gatherIngredients() override {
cout << "Gathering ingredients for breakfast: eggs, bread, and coffee." << endl;
}
void cook() override {
cout << "Cooking breakfast: frying eggs and toasting bread." << endl;
}
};
// Concrete subclass for preparing a lunch meal
class Lunch : public Meal {
public:
void gatherIngredients() override {
cout << "Gathering ingredients for lunch: chicken, rice, and vegetables." << endl;
}
void cook() override {
cout << "Cooking lunch: grilling chicken and steaming vegetables." << endl;
}
};
int main() {
Meal* breakfast = new Breakfast();
breakfast->prepareMeal();
cout << endl;
Meal* lunch = new Lunch();
lunch->prepareMeal();
// Clean up
delete breakfast;
delete lunch;
return 0;
}
Following is the output of the above code −
Gathering ingredients for breakfast: eggs, bread, and coffee. Cooking breakfast: frying eggs and toasting bread. Gathering ingredients for lunch: chicken, rice, and vegetables. Cooking lunch: grilling chicken and steaming vegetables. Serving the meal!
In this example, we have an abstract class called Meal. It has a main method named prepareMeal() that shows the full process of making a meal. The method includes three main steps â gathering ingredients, cooking, and serving.
The subclasses Breakfast and Lunch each add their own way of doing the steps. They give their own details for how to gather the ingredients and how to cook the food.
When we run the prepareMeal() method for each subclass, it follows the same main steps but changes the small details depending on the type of meal. This lets us keep the main process the same while still making each meal a little different.
Pros and Cons of the Template Method Design Pattern
Like any design pattern, the Template Method Design Pattern has its advantages and disadvantages. Here are some of the main pros and cons −
| Pros | Cons |
|---|---|
| It helps reuse code by keeping a common process in one place, so you don't have to write the same steps again and again. | It can create a strict class structure, which might make it harder to change the process later. |
| It keeps the process consistent across different parts of the program, so everything follows the same steps. | Subclasses don't have much freedom to change the main process, since the overall structure stays fixed. |
| It makes maintenance easier because the main process logic is all written in one place. | You might end up with too many subclasses if you need lots of small changes for different versions of the process. |
| It makes it easy to see and understand how the whole process works from start to finish. | Sometimes it can cause code duplication if different subclasses write the same steps in slightly different ways. |
Real-World Applications of the Template Method Design Pattern
The Template Method Design Pattern is widely used in various real-world applications. Here are some common scenarios where this pattern might be useful −
- Data Processing Pipelines − In data processing applications, a common sequence of steps such as data extraction, transformation, and loading (ETL) can be defined using the template method pattern. Different data sources or formats can be handled by subclasses that implement specific extraction and transformation logic.
- Game Development − In game development, the template method pattern can be used to define the overall game loop structure, while allowing subclasses to implement specific behaviors for different game states, such as playing, paused, or game over.
- Document Generation − In applications that generate documents (like reports or invoices), the template method pattern can define the overall structure of the document, while subclasses can implement specific formatting and content generation for different document types.
- User Interface Frameworks − UI frameworks often use the template method pattern to define the lifecycle of UI components, such as initialization, rendering, and event handling, while allowing subclasses to customize specific behaviors for different types of components.
- Testing Frameworks − Testing frameworks can use the template method pattern to define the overall structure of test cases, while allowing subclasses to implement specific setup, execution, and teardown logic for different types of tests.
Conclusion
The Template Method Design Pattern is a simple and practical way to keep one common process while letting different parts change only when it is needed. It helps you in reusing code, keeping your program organized, and make complex tasks easier to handle without repeating the same logic everywhere.