Template method design pattern
What is the template method design pattern?
The template method design pattern defines the skeleton of an algorithm in the superclass but lets subclasses override the algorithm without changing its structure. It is a behavioral design pattern
Advantages of template method design pattern:
- We can let clients override only certain parts of a large algorithm, making them less affected by changes that happen to other parts of the algorithm.
- We can pull the duplicate code into a superclass.
- Code reuse happens with the Template Method pattern as it uses inheritance and not composition
- Flexibility lets subclasses decide how to implement steps in an algorithm
Disadvantages of template method design pattern:
- Template methods tend to be harder to maintain the more steps they have
- We might violate the Liskov Substitution Principle by suppressing a default step implementation via a subclass
- Debugging and understanding the sequence of flow in the Template Method pattern can be confusing
Difference between Template method and Strategy design pattern
Template Method | Strategy |
---|---|
The abstract class defines the invariant behaviors, while the implementing classes defined the dependent methods | In a strategy, the behavior implementations are independent — each implementing class defines the behavior and there is no code shared between them |
Template method may define a set of public methods as well as a set of supporting private primitives that subclasses must implement | Strategies have a single public method — the execute() method |
It’s based on inheritance | It’s based on delegation/composition |
Parent class completely controls the algorithm and differs only in certain steps from concrete classes | It changes the behavior of the object at run time by completely replacing one algorithm with another algorithm at run time |
Binding is done at compile time | Binding is done at run time |
Example of template method design pattern:
// client.ts import PdfMiner from './subclass/PdfMiner' import JsonMiner from './subclass/JsonMiner' const dataMiner = new PdfMiner(); dataMiner.templateMethod(); console.log("=========================================="); const jsonMiner = new JsonMiner(); jsonMiner.templateMethod();Output:
PdfMiner says: I have implemented openFile PdfMiner says: I have implemented extractData PdfMiner says: I have implemented processData AbstractClass says: I am doing the data analysis work AbstractClass says: I will send the report after analyzing the data PdfMiner says: I have implemented closeFile ========================================== JsonMiner says: I have implemented openFile JsonMiner says: I have implemented extractData JsonMiner says: I have implemented processData AbstractClass says: I am doing the data analysis work AbstractClass says: I will send the report after analyzing the data JsonMiner says: I have implemented closeFile // DataMiner.ts export default abstract class DataMiner { /** * The template method defines the skeleton of an algorithm. */ public templateMethod(): void { this.openFile(); this.extractData(); this.processData(); this.analyzeData(); this.sendReport(); this.closeFile(); } /** * These operations already have implementations. */ protected analyzeData(): void { console.log('AbstractClass says: I am doing the data analysis work '); } protected sendReport(): void { console.log('AbstractClass says: I will send the report after analyzing the data'); } /** * These operations have to be implemented in subclasses. */ protected abstract openFile(): void; protected abstract extractData(): void; protected abstract processData(): void; protected abstract closeFile(): void; } // PdfMiner.ts import DataMiner from '../DataMiner' export default class PdfMiner extends DataMiner { protected openFile(): void { console.log('PdfMiner says: I have implemented openFile'); } protected extractData(): void { console.log('PdfMiner says: I have implemented extractData'); } protected processData(): void { console.log('PdfMiner says: I have implemented processData'); } protected closeFile(): void { console.log('PdfMiner says: I have implemented closeFile'); } } // JsonMiner.ts import DataMiner from '../DataMiner' export default class JsonMiner extends DataMiner { protected openFile(): void { console.log('JsonMiner says: I have implemented openFile'); } protected extractData(): void { console.log('JsonMiner says: I have implemented extractData'); } protected processData(): void { console.log('JsonMiner says: I have implemented processData'); } protected closeFile(): void { console.log('JsonMiner says: I have implemented closeFile'); } }
Source code: Template method design pattern github link