Template Method Design Pattern
Structural: Template Method
What is the Template Method design pattern in JavaScript?
View Answer:
This pattern's objects are as follows:
AbstractClass -- example code: datastore
- It provides a way for clients to use the template method.
- It uses the template method to define the basic steps of an algorithm.
- It provides hooks (through method overriding) for a client developer to use in implementing the Steps.
ConcreteClass -- example code: MySQL
- carries out the primitive Steps described in AbstractClass.
Here's an example of how to implement the Template Method pattern in modern JavaScript:
// This is the base class that contains the template method and common steps.
class Bread {
// This is the template method.
bakeBread() {
this.mixIngredients();
this.firstProving();
this.shapeDough();
this.secondProving();
this.bake();
}
// These are the steps that are the same for all breads.
mixIngredients() {
console.log('Ingredients mixed for standard bread.');
}
firstProving() {
console.log('First proving completed.');
}
shapeDough() {
throw new Error('You have to implement the method shapeDough!');
}
secondProving() {
console.log('Second proving completed.');
}
bake() {
throw new Error('You have to implement the method bake!');
}
}
// This is a concrete class that implements the varying steps.
class SourdoughBread extends Bread {
shapeDough() {
console.log('Dough shaped into a rustic loaf for sourdough bread.');
}
bake() {
console.log('Sourdough bread baked at 230 degrees Celsius for 40 minutes.');
}
}
// This is another concrete class that implements the varying steps.
class Baguette extends Bread {
shapeDough() {
console.log('Dough shaped into a long, thin cylinder for baguette.');
}
bake() {
console.log('Baguette baked at 240 degrees Celsius for 20 minutes.');
}
}
// Usage:
let bread = new SourdoughBread();
bread.bakeBread();
bread = new Baguette();
bread.bakeBread();
When you run this program, you'll see the steps of baking bread printed out. The steps that are the same for all breads are implemented in the base class, while the steps that can vary depending on the type of bread (shaping the dough and baking) are implemented in the subclasses. The bakeBread
method in the base class is the template method, and it dictates the sequence of steps for baking bread.
What pattern category does the template method pattern belong to?
View Answer:
Can you give an example of when to use the Template Method?
View Answer:
When to Use the Template Method Pattern:
- The template method pattern solves the problem by employing an algorithm with various versions. You need to divide your method into additional steps implemented in the abstract class when the different implementations share them. On the other hand, we implement the various steps in the concrete classes.
- Another compelling use case for this approach is when you have copied and pasted code (private functions) between various classes.
- Finally, you can employ this strategy if most of your classes exhibit similar tendencies.
What are some of the benefits of using the Template Method pattern?
View Answer:
- It's relatively easy to create a concrete implementation of an algorithm because you're removing common parts of the problem domain using an abstract class.
- Clean code because you avoid duplicate code.
- Ever cleaner code because you separate the algorithm into private methods or functions that are simpler and easier to test.
What are some disadvantages of employing the Template Method design pattern?
View Answer:
- You may violate the Liskov Substitution Principle by suppressing a default step implementation through a subclass.
- Some clients may be the only reason the template pattern imposes a specific design.
- The template design is more adaptable than other patterns, and modifications at the high or low level might disrupt implementation, making maintenance difficult.
Are there any alternatives to using the Template Method?
View Answer:
How does the Template Method contribute to code reuse?
View Answer:
What are the key components of the Template Method pattern?
View Answer:
// Abstract base class
class AbstractClass {
// Template method
templateMethod() {
this.primitiveOperation1();
this.primitiveOperation2();
}
// Default operation
primitiveOperation1() {
console.log('Primitive operation 1 from AbstractClass');
}
// Abstract operation
primitiveOperation2() {
throw new Error('You have to implement the method primitiveOperation2!');
}
}
// Concrete subclass
class ConcreteClass extends AbstractClass {
// Overriding abstract operation
primitiveOperation2() {
console.log('Primitive operation 2 from ConcreteClass');
}
}
// Usage:
let instance = new ConcreteClass();
instance.templateMethod();
In this code:
AbstractClass
is the abstract base class. It contains the template method (templateMethod
), a default step method (primitiveOperation1
), and an abstract step method (primitiveOperation2
).templateMethod
is the template method. It callsprimitiveOperation1
andprimitiveOperation2
in a specific order.primitiveOperation1
is a default step method, which is defined in the base class and is the same for all subclasses.primitiveOperation2
is an abstract step method, which must be implemented by each subclass.ConcreteClass
is a concrete subclass that inherits fromAbstractClass
and implementsprimitiveOperation2
.
When you run this code, the output demonstrates that the template method has dictated the order of execution of the operations and that the operation overridden in the subclass has been successfully executed.
How does the Template Method maintain the Open/Closed Principle?
View Answer:
How do the Template Method and the Strategy Pattern differ?
View Answer:
What is a potential downside of the Template Method pattern?
View Answer:
Can the Template Method pattern lead to problems in JavaScript due to its prototypal inheritance?
View Answer:
Is it common to use the Template Method pattern in functional programming?
View Answer:
Can the Template Method pattern be used with JavaScript's ES6 class syntax?
View Answer:
// Abstract class
class AbstractClass {
// Template method
templateMethod() {
this.primitiveOperation1();
this.primitiveOperation2();
}
primitiveOperation1() {
console.log('Primitive operation 1 is running...');
}
primitiveOperation2() {
throw new Error('Method \'primitiveOperation2\' is not implemented');
}
}
// Concrete class
class ConcreteClass extends AbstractClass {
primitiveOperation2() {
console.log('Primitive operation 2 is running...');
}
}
// Usage:
const concreteInstance = new ConcreteClass();
concreteInstance.templateMethod();
In this example, AbstractClass
is the abstract class with a template method (templateMethod
) and two primitive operations. ConcreteClass
is a concrete class that extends AbstractClass
and implements primitiveOperation2
. This code runs the template method on an instance of ConcreteClass
, which executes the two primitive operations in order.