[JavaScript Design Patterns] Behavioral Design Patterns -- Template Method Patterns

Posted by ball420 on Sat, 29 Jun 2019 01:42:11 +0200

Template method pattern is a very simple pattern that can be implemented with inheritance only. Template method pattern is composed of two parts. The first part is abstract class, and the second part is concrete implementation subclass. Generally, the algorithmic framework of subclasses is encapsulated in abstract parent classes, which mainly includes some common methods and the execution order of all methods in all subclasses. That subclass inherits the abstract class, that is, inherits the entire algorithm structure, and can choose to override the method of the parent class.

Another design principle, the Hollywood Principle, was introduced into the template method model. To illustrate this principle, a paragraph is introduced here:

      | Hollywood is undoubtedly a paradise for actors, but there are many new actors in Hollywood who can't find a job. Many new actors have to go home and wait for the phone after they hand their resumes to the Performing Arts company. Sometimes the actors are impatient and call the performing arts company for information. The performing arts company often replies, "Don't come to me, I'll call you." Such a rule is called the Hollywood rule.

Template method pattern is a typical application scenario of Hollywood Principles, and its connection with Hollywood Principles is very obvious. When we use template method to write a program, it means that the subclass gives up its control over itself, but instead notifies the subclass of the parent class which methods should be called when. As a subclass, it is only responsible for providing some design details.

The following is a specific example of Coffee and Tea to illustrate the use of template method patterns.

Coffee and tea are very classic examples, often used to explain template method patterns.

1. Make a cup of coffee

The steps for making coffee are usually as follows:

  1. Boil the water.
  2. Make coffee with boiling water.
  3. Pour the coffee into the cup.
  4. Sugar and milk.
We implement this process by code:
var Coffee = function(){};

Coffee.prototype.boilWater = function(){
	console.log('1.Boil the water');
}

Coffee.prototype.brewCoffeeGriends = function(){
	console.log('2.Brew coffee with boiling water');
}

Coffee.prototype.pourIncup = function(){
	console.log('3.Pour the coffee into the cup');
}

Coffee.prototype.addSugarAndMilk = function(){
	console.log('4.Sugar and milk');
}

Coffee.prototype.init = function(){
	this.boilWater();
	this.brewCoffeeGriends();
	this.pourIncup();
	this.addSugarAndMilk();
}

var coffee = new Coffee();
coffee.init();

2. Make a pot of tea

The steps for making a pot of tea are usually as follows:

  1. Boil the water.
  2. Soak tea in boiling water.
  3. Pour the tea into the cup.
  4. Add lemon.
We implement this process by code:

//Make tea
var Tea = function(){};

Tea.prototype.boilWater = function(){
	console.log('1.Boil the water');
}

Tea.prototype.brewCoffeeGriends = function(){
	console.log('2.Soak tea in boiling water');
}

Tea.prototype.pourIncup = function(){
	console.log('3.Pour the tea into the cup');
}

Tea.prototype.addSugarAndMilk = function(){
	console.log('4.Add lemon');
}

Tea.prototype.init = function(){
	this.boilWater();
	this.brewCoffeeGriends();
	this.pourIncup();
	this.addSugarAndMilk();
}

var tea = new Tea();
tea.init();
3. Separating Common Points

Comparing making coffee with making tea, the following steps can be summarized:

  1. Boil the water.
  2. Drinks are brewed with boiling water.
  3. Pour the drink into the cup.
  4. Add seasoning.
Now we abstract a class to represent the whole process of making a drink. The implementation code is as follows:
var Beverage = function(){};

Beverage.prototype.boilWater = function(){
	console.log("1.Boil the water");
};

Beverage.prototype.brew = function(){};//Empty methods should be overridden by subclasses

Beverage.prototype.pourIncup = function(){};//Empty methods should be overridden by subclasses

Beverage.prototype.addCondiments = function(){};//Empty methods should be overridden by subclasses

Beverage.prototype.init = function(){
	this.boilWater();
	this.brew();
	this.pourIncup();
	this.addCondiments();
}
4. Implementing Coffee and Tea subclasses
Next we need to create concrete implementations of coffee and tea.

Coffee:

var Coffee = function(){};
Coffee.prototype = new Beverage();
Coffee.prototype.brew = function(){
	console.log('2.Brew coffee with boiling water');
};
Coffee.prototype.pourIncup = function(){
	console.log('3.Pour the coffee into the cup');
}
Coffee.prototype.addCondiments = function(){
	console.log('4.Sugar and milk');
}

var coffee = new Coffee();
coffee.init();

Tea:

var Tea = function(){};
Tea.prototype = new Beverage();
Tea.prototype.brew = function(){
	console.log('2.Brew coffee with boiling water');
};
Tea.prototype.pourIncup = function(){
	console.log('3.Pour the coffee into the cup');
}
Tea.prototype.addCondiments = function(){
	console.log('4.Sugar and milk');
}

var tea = new Tea();
tea.init();
5. Summary

The template method is applied to the following cases:

  1. Implement the invariant part of an algorithm at one time and leave the variable behavior to the subclass for implementation
  2. Common behavior in each subclass should be extracted and centralized into a common parent class to avoid code duplication. The differences are separated into new operations and implemented separately.
  3. Controlling subclass extensions, template methods can invoke "Hook" operations only at specific points, so that extensions are allowed only at those points.




Topics: brew