What is the template method design pattern

Literally, a template method is defined as a set of methods that serve as a template, the foundation. On this basis, we can process, to achieve personalized realization. For example, eat three meals a day. Breakfast, lunch, dinner. Everyone eats three meals, but everyone’s meals may be different. Three meals a day define the template — morning, noon and night, and each person’s meal is the realization of the template.

1.1 Purpose of template method:

  1. Move immutable behavior from subclasses to superclasses, removing duplicate code from subclasses.
  2. Regulate the structure of subclasses

1.2 Definition of template methods

Defining the skeleton of an algorithm in an operation and deferring some steps of the algorithm to a subclass allows the subclass to redefine specific steps of the algorithm without changing the structure of the algorithm. It’s a behavioral pattern.

Steps for defining template methods

Step 1: Define template class step 2: Define concrete subclass Step 3: client call

Here’s a look at each step:

2.1 Defining template classes

Usually a template class is an abstract class that gives the outline or framework of an algorithm. It is composed of several template methods and several basic methods.

  1. Template method

    Defines the skeleton of the algorithm, defines the order of method calls, including one or more basic methods

  2. Basic method

    There are three types of basic algorithms:

    A) Abstract methods: methods that subclasses must override. There is no default implementation.

    B) Concrete method: the default implementation of a superclass definition with implementation logic that can be inherited or overridden by concrete subclasses

    C) Hook methods: logical methods for judgment and empty methods that need to be overridden by subclasses.

2.2 Defining specific subclasses

Concrete subclasses, or concrete implementation classes, implement abstract methods in abstract classes. They are an integral part of the abstract template method.

2.3 Defining client Calls

When a client calls an abstract class and instantiates a concrete class, it simply calls the template method of the abstract class.

2.4 Let’s look at UML diagrams and source code implementations between abstract classes and subclasses

  1. UML diagrams

You can see from the figure that the structure of an abstract class can define three types of methods. You can have one or you can have multiple. Subclasses must implement abstract methods in an abstract class and can optionally override the concrete methods of their parent class. When subclassing interfaces, think about the six principles of design patterns.

  1. The source code

    Start by defining the abstract class, which is the framework.

package com.lxl.www.designPatterns.templatePattern.template;

/** * abstract class, define template */
public abstract class AbstractClass {

    /** * Defines the template method * that defines the framework of the process */
    public void templateMethod(a) {
        // Call the concrete method first
        specificMethod();
        // Call the abstract method
        abstractMethod();
    }

    /** ** specific method */
    public void specificMethod(a) {
        // Concrete public logic, parent class common
        System.out.println("Concrete method - Parent general Logic");
    }

    /** * abstract methods ** Abstract methods, subclasses must override */
    public abstract void abstractMethod(a);

}

Copy the code

In the definition of a concrete implementation class, the implementation of the parent class abstract method

package com.lxl.www.designPatterns.templatePattern.template;

/** * concrete implementation class */
public class ConcreteClass extends AbstractClass{

    /** * overrides the abstract method */ of the parent class
    @Override
    public void abstractMethod(a) {
        System.out.println("Concrete implementation classes -- Abstract methods that override the parent class"); }}Copy the code

Finally, define the client call

package com.lxl.www.designPatterns.templatePattern.template;

/** * template method client */
public class TemplateClient {
    public static void main(String[] args) {
        AbstractClass abstractClass = newConcreteClass(); abstractClass.templateMethod(); }}Copy the code

Running results:

Concrete methods – the parent class generic logic concrete implementation class – overrides the parent class’s abstract methods

In contrast to the template approach to design patterns, let’s look at a specific case.

Three cases,

1. Case 1: One-day planning

Everyone has three meals a day, breakfast, lunch and dinner. But everyone’s meals are different, so let’s take a look at how they change and what to do before and after each meal.

package com.lxl.www.designPatterns.templatePattern.oneDayArrangement;

/** * three meals a day */
public abstract class ArrangementAbstract {

    /** * the template method specifies the framework for the day */
    public void templateMethod(a) {
        System.out.println("The day is arranged as follows:");
        getUp();
        breakfast();
        lunch();
        dinner();
        getDown();
    }

    public void getUp(a) {
        System.out.println("Wake up");
    }

    public void getDown(a) {
        System.out.println("Sleep");
    }

    /** * breakfast abstract class */
    public abstract void breakfast(a) ;

    /** * Lunch abstract class */
    public abstract void lunch(a);

    /** * dinner abstract class */
    public abstract void dinner(a);

}

Copy the code

Define three abstract meals a day. Everyone’s schedule is wake up, breakfast, lunch, dinner, bed. Everyone has to get up and go to bed, and so do three meals, but the food for three meals is different, so we define three meals as abstract

A day schedule implementation class

package com.lxl.www.designPatterns.templatePattern.oneDayArrangement;

/** * Zhang SAN's three meals a day */
public class PersonArrangement extends ArrangementAbstract{
    private String name;
    public PersonArrangement(String name) {
        this.name = name;
    }

    /** * breakfast abstract class */
    public void breakfast(a){
        System.out.println(name + "-- Milk and bread for breakfast");
    }

    /** * Lunch abstract class */
    public void lunch(a) {
        System.out.println(name + "-- Dining hall for Chinese food");
    }

    /** * dinner abstract class */
    public void dinner(a) {
        System.out.println(name + "-- Fruit for dinner."); }}Copy the code

Client call

public class Client {
    public static void main(String[] args) {
        ArrangementAbstract zhangsan = new PersonArrangement("Zhang"); zhangsan.templateMethod(); }}Copy the code

Running results:

One day arrangement is as follows: get up zhang SAN – eat milk bread zhang SAN for breakfast – eat lunch dining room Zhang SAN – eat fruit for dinner to sleep

As you can see, follow the steps of the template approach.

2. Case 2: Hook method

As we mentioned above, the basic methods in the template method design pattern include abstract methods, concrete methods, and hook methods. If you use good hook methods, you can perfectly implement subclasses to control the behavior of their parent classes. Let’s look at the following example:

In the abstract method we define a hookMethod, hookMethod(). In the templateMethod, templateMethod(), the hookMethod controls the flow of the code.

UML diagrams:

The source code:

package com.lxl.www.designPatterns.templatePattern.hookMethod;

/** * abstract class, define template */
public abstract class AbstractClass {

    /** * Defines the template method * that defines the framework of the process */
    public void templateMethod(a) {
        // Call the concrete method
        specificMethod();
        The hook method controls the next step
        if (hookMethod()) {
            // Call the abstract methodabstractMethod(); }}/** ** specific method */
    public void specificMethod(a) {
        // Concrete public logic, parent class common
        System.out.println("Concrete method - Parent general Logic");
    }

    /** * the hook method is implemented, */
    public boolean hookMethod(a) {
        return true;
    }

    /** * abstract methods ** Abstract methods, subclasses must override */
    public abstract void abstractMethod(a);

}
Copy the code

Define concrete implementation

/** * concrete implementation class */
public class ConcreteClass extends AbstractClass {

    /** * overrides the abstract method */ of the parent class
    @Override
    public void abstractMethod(a) {
        System.out.println("Concrete implementation classes -- Abstract methods that override the parent class");
    }

    /** * hook method *@return* /
    @Override
    public boolean hookMethod(a) {
        System.out.println(Overrides the parent's hook method to reverse the parent's behavior.);
        return false; }}Copy the code

Overrides hook methods to reverse the behavior of the parent class

public class TemplateClient {
    public static void main(String[] args) {
        AbstractClass abstractClass = newConcreteClass(); abstractClass.templateMethod(); }}Copy the code

The results

Concrete methods – parent generic logic overrides the parent’s hook methods and reversely controls the parent’s behavior

If the code for the subclass HookMethod HookMethod() changes, the results of the program will also change.

Advantages and disadvantages of the template method

4.1 the advantages

  1. It standardizes the framework, encapsulates the invariable part, and extends the variable part. The parent class defines the framework and abstracts the common immutable parts, while the subclass completes the implementation of the framework by overwriting extensions.
  2. The “open closed principle” is used, open for extensions, closed for modifications. Subclasses can extend the implementation of a parent class by overriding its abstract methods.
  3. Behavior sets have parent class control, standardize the flow

4.2 disadvantages

  1. Each implementation needs to define a concrete implementation class, increasing the number of classes and making the system more complex
  2. The disadvantage of inheritance is that once the parent class adds an abstract method, all subclasses need to add it. This violates the “open close principle “.
  3. Abstract methods in the parent class are implemented by the child class, and the result of the execution of the child class affects the parent class. This “reverse control” structure can increase code complexity.

Five. Application scenarios

  1. When the overall steps of the algorithm are fixed, but some parts are prone to change, the template method can be considered to design the pattern, and the parts that are prone to change can be abstracted out and provided to the subclasses for implementation.
  2. When multiple subclasses have common behavior, they can be extracted and grouped into a common parent class to avoid code duplication. First, you identify the differences in existing code and separate them into new operations. Finally, replace the different code with a template method that calls the new operations.
  3. When you need to control the extension of a subclass, the template method calls hook operations only at certain points, allowing extension only at those points.
  4. In refactoring, the template method pattern is a frequently used pattern that extracts the same code into a parent class and constrains its behavior with hook functions

Vi. Thinking about the application of six principles of design pattern

  1. Single responsibility principle: a method has only one cause for change, which is not easy to see, to open the concrete implementation of the subclass code
  2. The li substitution principle: subclass substitution can be used wherever the parent appears, and the result remains the same. A subclass overrides the methods of its parent class. The template approach design pattern may violate the formula substitution principle, but this is the principle of “reverse control”
  3. Interface isolation principle: Rely on the smallest single interface, not the fat interface. Conform to the
  4. Dependency inversion principle: Rely on the abstract, not the concrete. Conform to the
  5. Demeter’s Law: The least knowledge principle. Talk to your friends and cut down on them. This depends on the subclass implementation
  6. Open closed principle: Violating the open closed principle, once the parent class adds an abstract method, all subclasses need to add it accordingly