Template method pattern
Introduction
The template method pattern is a simple and commonly used design pattern. It is a code reuse technology based on class inheritance. Its structure only has the inheritance relationship between the base class and the derived class. A template method is a concrete method that gives a top-level logical flow framework.
Template Method Pattern: Define the framework of an algorithm in operation, and defer some steps to subclasses, so that subclasses can redefine some specific steps of an algorithm without changing the structure of the algorithm. The specific method implemented by the subclass is called the basic method, and the framework method that realizes the height of the basic method is called the template method.
structure
accomplish
#ifndef __DEMO_H__ #define __DEMO_H__ // abstract class (base class) class AbstractClass { public: void templateMethod() { // do something method1(); method2(); method3(); } // Basic method - public method void method1() { // do something } // Basic method 2 virtual void method2() = 0; // Basic Method 3 - Default Implementation void method3() { // do something } }; // Concrete class (derived class) class ConceteClass: public AbstractClass { public: // void method2() { // do something } // void method3() { // do something } }; #endif
example
Problem Description
A certain fingerprint processing module can process algorithms in two modes, secure mode and non-secure mode. In security mode, in order to ensure data security, a fingerprint identification process needs to encrypt the acquired fingerprint image, and then decrypt the encrypted data before processing the image. Instead of safe mode this does not require an encryption decryption process. The fingerprint algorithm process is as follows: image acquisition - encryption - decryption - algorithm processing fingerprint - processing results. Now use the template method pattern to simulate the above process.
Questions and Answers
// FingerprintModule.h // base class class FingerprintModule { public: FingerprintModule(){} void getImage(){ printf("Fingerprint image\n"); } void output(){ printf("Fingerprint image processing completed!\n"); } virtual bool isSafeMode() = 0; virtual void processImage() = 0; // Encryption and decryption virtual void encrypt() = 0; virtual void decrypt() = 0; // Template method void algorithm(){ // 1. Mapping getImage(); // 2. Encrypt and decrypt in safe mode if (isSafeMode()){ // 2.1. Encryption encrypt(); // 2.2. Decryption decrypt(); } // 3. Process Image processImage(); // 4. Processing results output(); } }; // Derived class class FingerprintModuleA :public FingerprintModule { public: FingerprintModuleA(){} void processImage(){ printf("Process the fingerprint image using the first generation version of the algorithm\n"); } bool isSafeMode(){ printf("safe mode\n"); return true; } void encrypt(){ printf("use RSA key encryption\n"); } void decrypt(){ printf("use RSA key decryption\n"); } }; // Derived class class FingerprintModuleB :public FingerprintModule { public: FingerprintModuleB(){} void processImage(){ printf("Process the fingerprint image using the second generation version of the algorithm\n"); } bool isSafeMode(){ printf("non-safe mode\n"); return false; } void encrypt(){} void decrypt(){} }; // Derived class class FingerprintModuleC :public FingerprintModule { public: FingerprintModuleC(){} void processImage(){ printf("Process the fingerprint image using the first generation version of the algorithm\n"); } bool isSafeMode(){ printf("safe mode\n"); return true; } void encrypt(){ printf("use DH key encryption\n"); } void decrypt(){ printf("use DH key decryption\n"); } };
// example.cpp #include "FingerprintModule.h" int main(int argc, char *argv[]) { FingerprintModule *fp = new FingerprintModuleA(); fp->algorithm(); printf("\n"); fp = new FingerprintModuleB(); fp->algorithm(); printf("\n"); fp = new FingerprintModuleC(); fp->algorithm(); return 0; }
Summarize
advantage
- The framework of the algorithm is defined in the base class, and some process methods are declared. There are specific derived classes to implement specific details. The implementation in the derived class does not affect the framework process of the algorithm defined by the base class.
- Public behaviors are implemented in base classes, which facilitates code reuse.
- Derived classes can override the methods of the base class and re-implement some methods with flexibility.
- Derived classes can be easily extended and replaced without affecting the base class and other derived classes. Comply with the Open-Closed Principle and Single Responsibility Principle.
shortcoming
- The template method pattern defines the method of the subclass in the abstract class, that is, the subclass has an impact on the parent class, which partially affects the readability of the code.
- The more steps in a template method, the more difficult it can be to maintain.
Scenes
- By dividing complex algorithms, the framework process of the algorithm can be defined in the base class, which is designed as a template method, and the specific details are designed and implemented by the derived class. For example, there are many supervised learning algorithms in machine learning, such as decision tree, KNN, SVN, etc., but the process is roughly the same, including input samples, fitting, prediction and other processes, extract these processes, construct template methods, and pass Hook methods control the flow.
- The common parts of each derived class are extracted into the base class for code reuse.
- Derived classes need to override certain methods of the base class.
Relationship to other modes
- The Factory Method pattern is a special form of the Template Method pattern. At the same time, a factory method can be used as a step in a larger template method.
- The template method is based on inheritance: it allows you to change parts of the algorithm by extending parts of the subclass. The strategy pattern is based on the composition mechanism: you can change part of the behavior of an object by providing different strategies for the corresponding behavior. The template method pattern operates at the class level, so it is static. Whereas the strategy pattern operates at the object level, so the operation switches behavior at runtime.