The application of Template Method template method pattern in C++ design pattern programming

  • 2020-05-09 18:58:37
  • OfStack

Prepare an abstract class, implement some of the logic in the form of concrete methods and concrete constructors, and then declare some abstract methods to force subclasses to implement the rest of the logic. Different subclasses can implement these abstract methods in different ways, resulting in different implementations of the rest of the logic. This is what the template method pattern is all about.

Many people may not realize that the template method pattern is actually one of the most common patterns of all, and many people may have used the template method pattern without realizing that they have used it. The template method pattern is the basic technology of code reuse based on inheritance. The structure and usage of the template method pattern are also the core of object-oriented design.

The template method pattern requires collaboration between designers who develop abstract classes and concrete subclasses. One designer was responsible for giving the outline and skeleton of an algorithm, and another designer was responsible for giving the logical steps of the algorithm. The method that represents these specific logical steps is called the basic method (primitive method); The way to aggregate these basic methods is called template method (template method), hence the name of the design pattern.

Method in the template method pattern

Methods in template methods can be divided into two categories: template methods (Template Method) and basic methods (Primitive Method).

Template method

A template method is a method defined in an abstract class that combines basic operations to form a summary method or a total behavior. This template method 1 is generally defined in the abstract class and is completely inherited by the subclass without modification.

Basic method

There are three basic methods: the abstract method (Abstract Method), the concrete method (Concrete Method), and the hook method (Hook Method).

Abstract method: an abstract method is declared by an abstract class and implemented by a concrete subclass. In C#, an abstract method is marked with the abstract keyword. Concrete method: a concrete method is declared and implemented by an abstract class, and subclasses do not implement or displace it. In the C# language, a specific method does not have the abstract keyword. Hook methods: a hook method is declared and implemented by an abstract class that is extended by a subclass. Usually the implementation given by an abstract class is an empty implementation as the default implementation of a method. (a project created by the project wizard in Visual FoxPro USES an AppHook class to monitor changes in project members and adjust the structure of the system.) The name of the hook method usually begins with do.


Implementation of the template method pattern

Complete code example (code) : the template method pattern implementation is very simple, here for beginners to learn and reference, will give the complete implementation code (all code using C++ implementation, and VC 6.0 under the test run).

Code snippet 1: Template.h


//Template.h
#ifndef _TEMPLATE_H_
#define _TEMPLATE_H_
class AbstractClass{
  public:
  virtual ~AbstractClass();
  void TemplateMethod();
  protected:
  virtual void PrimitiveOperation1() = 0;
  virtual void PrimitiveOperation2() = 0;
  AbstractClass();
  private:
};
class ConcreteClass1:public AbstractClass{
  public:
  ConcreteClass1();
  ~ConcreteClass1();
  protected:
  void PrimitiveOperation1();
  void PrimitiveOperation2();
  private:
};
class ConcreteClass2:public AbstractClass{
  public:
   ConcreteClass2();
  ~ConcreteClass2();
  protected:
  void PrimitiveOperation1();
  void PrimitiveOperation2();
  private:
};
#endif //~_TEMPLATE_H_

Code snippet 2: Template.cpp


#include "Template.h"
#include <iostream>
using namespace std;
AbstractClass::AbstractClass(){
}
AbstractClass::~AbstractClass(){
}
void AbstractClass::TemplateMethod(){
   this->PrimitiveOperation1();
  this->PrimitiveOperation2();
}
ConcreteClass1::ConcreteClass1(){
}
ConcreteClass1::~ConcreteClass1(){
}
void ConcreteClass1::PrimitiveOperation1(){
  cout<<"ConcreteClass1...PrimitiveOperat
  ion1"<<endl;
}
void ConcreteClass1::PrimitiveOperation2(){
  cout<<"ConcreteClass1...PrimitiveOperat
  ion2"<<endl;
}
ConcreteClass2::ConcreteClass2(){
}
ConcreteClass2::~ConcreteClass2(){
}
void ConcreteClass2::PrimitiveOperation1(){
cout<<"ConcreteClass2...PrimitiveOperat
ion1"<<endl;
}
void ConcreteClass2::PrimitiveOperation2(){
  cout<<"ConcreteClass2...PrimitiveOperat
  ion2"<<endl;
}

Code snippet 3: main.cpp


#include "Template.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[]){
  AbstractClass* p1 = new ConcreteClass1();
  AbstractClass* p2 = new ConcreteClass2();
  p1->TemplateMethod();
  p2->TemplateMethod();
  return 0;
}

Code description: because the template method pattern implementation code is very simple, so the explanation is redundant. The key is to encapsulate the generic algorithm (logic) and let subclasses implement the algorithm details (polymorphism).

Note only that we have defined the primitive operation (detail algorithm) as an unprotected (Protected) member for template method calls only (subclasses can).


Applicable scenario
Implement the invariant part of an algorithm and leave the variable behavior to subclasses.
The common behavior in each subclass should be extracted and concentrated into a common parent class to avoid code duplication. This is a good example of what O p d y e and J o h n s o n describe as "refactorization as 1" [O J 93]. Start by identifying the differences in existing code and separating them into new operations. Finally, replace the different code with a template method that calls these new operations.
Control subclass extension. The template method only calls the "h o o k" operation at a specific point (see effects 1), so that only these points are allowed to be extended.


Related articles: