Definition and characteristics of pattern
The definition of Template Method pattern is as follows: define the algorithm skeleton in an operation, and delay some steps of the algorithm to the subclass, so that the subclass can redefine some specific steps of the algorithm without changing the structure of the algorithm. It is a kind of behavioral model.
The main advantages of this mode are as follows.
- It encapsulates the invariant part and extends the variable part. It encapsulates the algorithm that is considered to be the invariant part into the parent class, and inherits the variable part algorithm from the subclass, which is convenient for the subclass to continue to expand.
- It extracts part of the common code from the parent class to facilitate code reuse.
- Some methods are implemented by subclasses, so subclasses can add corresponding functions through extension, which conforms to the opening and closing principle.
The main disadvantages of this model are as follows.
- It is necessary to define a subclass for each different implementation, which will increase the number of classes, make the system larger and the design more abstract, and indirectly increase the complexity of the system implementation.
- Abstract methods in the parent class are implemented by subclasses, and the execution results of subclasses will affect the results of the parent class, which leads to a reverse control structure, which improves the difficulty of code reading.
- Due to the shortcomings of the inheritance relationship itself, if a new abstract method is added to the parent class, all subclasses must be changed again.
Structure and implementation of pattern
The template method pattern needs to pay attention to the cooperation between abstract classes and concrete subclasses. It uses the polymorphism technology of virtual functions and the reverse control technology of "don't call me, let me call you". Now let's introduce their basic structure.
1. Structure of the model
The template method pattern contains the following main roles.
1) Abstract Class / Abstract Class
Abstract template class, which is responsible for giving the outline and skeleton of an algorithm. It consists of a template method and several basic methods. These methods are defined as follows.
① Template method: defines the skeleton of the algorithm and calls its basic methods in a certain order.
② Basic method: it is a step in the whole algorithm, including the following types.
- Abstract method: declared in an abstract class and implemented by a concrete subclass.
- Concrete method: it has been implemented in an abstract class and can be inherited or overridden in a concrete subclass.
- Hook method: it has been implemented in abstract classes, including logical methods for judgment and empty methods that need to be overridden by subclasses.
2) Concrete Class
The concrete implementation class implements the abstract methods and hook methods defined in the abstract class, which are a constituent step of a top-level logic.
The structure diagram of template method mode is shown in Figure 1.
2. Implementation of mode
The code of template method mode is as follows:
public class TemplateMethodPattern { public static void main(String[] args) { AbstractClass tm = new ConcreteClass(); tm.TemplateMethod(); } } //abstract class abstract class AbstractClass { //Template method public void TemplateMethod() { SpecificMethod(); abstractMethod1(); abstractMethod2(); } //Specific method public void SpecificMethod() { System.out.println("Concrete methods in abstract classes are called..."); } //Abstract method 1 public abstract void abstractMethod1(); //Abstract method 2 public abstract void abstractMethod2(); } //Specific subclass class ConcreteClass extends AbstractClass { public void abstractMethod1() { System.out.println("The implementation of abstract method 1 is called..."); } public void abstractMethod2() { System.out.println("The implementation of abstract method 2 is called..."); } }
Application scenario of pattern
The template method pattern is generally applicable to the following scenarios.
- The overall steps of the algorithm are very fixed, but when individual parts are changeable, you can use the template method pattern to abstract the easily changeable parts for subclass implementation.
- When several subclasses have common behavior, they can be extracted and concentrated in a common parent class to avoid code duplication. First, identify the differences in the existing code and separate the differences into new operations. Finally, replace the different code with a template method that calls these new operations.
- When you need to control the extension of subclasses, template methods only call hook operations at specific points, so you are only allowed to extend at these points.
Mode extension
In the template method pattern, the basic methods include abstract methods, concrete methods and hook methods. The correct use of "hook methods" can enable the subclass to control the behavior of the parent class. As in the following example, you can change the running result in the abstract parent class by overriding hook methods HookMethod1() and HookMethod2() in the specific subclass. Its structure is shown in Figure 3.
public class HookTemplateMethod { public static void main(String[] args) { HookAbstractClass tm = new HookConcreteClass(); tm.TemplateMethod(); } } //Abstract class with hook method abstract class HookAbstractClass { //Template method public void TemplateMethod() { abstractMethod1(); HookMethod1(); if (HookMethod2()) { SpecificMethod(); } abstractMethod2(); } //Specific method public void SpecificMethod() { System.out.println("Concrete methods in abstract classes are called..."); } //Hook method 1 public void HookMethod1() { } //Hook method 2 public boolean HookMethod2() { return true; } //Abstract method 1 public abstract void abstractMethod1(); //Abstract method 2 public abstract void abstractMethod2(); } //Concrete subclass with hook method class HookConcreteClass extends HookAbstractClass { public void abstractMethod1() { System.out.println("The implementation of abstract method 1 is called..."); } public void abstractMethod2() { System.out.println("The implementation of abstract method 2 is called..."); } public void HookMethod1() { System.out.println("Hook method 1 is overridden..."); } public boolean HookMethod2() { return false; } }
If the code of hook method HookMethod1() and hook method HookMethod2() changes, the running result of the program will also change.