Learn "Template Method Model" in one minute

Posted by edwin_h on Sat, 11 May 2019 01:15:48 +0200

Preface

Only a bald head can be stronger.

The text has been included in my GitHub warehouse. Welcome to Star: https://github.com/ZhongFuCheng3y/3y

In the last article, a reader said that one minute will be the end of the facade model, so today's title is "One minute Learn Template Method Model".

Looking back on the design patterns that have been written before:

Design patterns are necessary for both interviews and personal advancement. Today I'm going to talk about the template approach pattern.~

I. Template Method Patterns

1.1 Template Method Model Practical Example

As you all know, every time I write original technical articles, there will always be "only a bald head can become stronger". Of course, I can't copy this sentence every time I write an article (because it's too troublesome).

I have my own writing template to show you:

The foreword and the end are fixed. As for the first point and the second point, we have to see what articles we write, and the corresponding contents of different articles are different.

Every time I write an article, as long as I add what I want to write on this template, I don't have to copy the same content every time, which greatly reduces my workload.

1.2 Back to the Code World

Code comes from life. Similarly, I can describe the process of my writing in code. Let's take a look at it.

Every article of 3y will have the contents of "Preface" and "Last", and 3y writes out these two modules.


// 3y article template
public class Java3yWriteArticle {
    
    // Preface
    public void introduction() {
        System.out.println("Only a bald head can grow stronger");
    }

    // Last
    public void theLast() {
        System.out.println("Pay attention to my public number: Java3y");

    }
}

When 3y writes an article, 3y may use this way:


    // 3y writes articles
    public static void main(String[] args) {

        Java3yWriteArticle writeArticle = new Java3yWriteArticle();

        // Preface
        writeArticle.introduction();

        // Actual content
        System.out.println("Hello, everyone. I'm 3. y,Today I'm going to share with you the template method pattern I've written.");

        // Last
        writeArticle.theLast();
    }

This can accomplish the function of 3y writing articles, but how about doing so? At this time, 3y girlfriend also wants to write articles, and her articles also want to have two modules: "Preface" and "Last", so the article template of 3y girlfriend is as follows:


// 3y girlfriend's article template
public  class Java3yGFWriteArticle {

    // Preface
    public void introduction() {
        System.out.println("balabalabalalabalablablalab");
    }

    // Last
    public void theLast() {
        System.out.println("balabalabalalabalablablalab");

    }
}

When your 3y girlfriend writes an article, she may use it as well:


    // 3y Girlfriend Writes Articles
    public static void main(String[] args) {
        Java3yGFWriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();

        // Preface
        java3yGFWriteArticle.introduction();

        // Actual content
        System.out.println("3y It's a fool. Don't care about him.");

        // Last
        java3yGFWriteArticle.theLast();

    }

It can be found that when 3Y and 3Y girlfriends want to write articles, they call introduction(); and the Last (); repeatedly. Moreover, the "preface" and "last" in 3y's article template and 3y's girlfriend's article template are only different in content, but they define twice, which is obviously duplicate code. What do we do with duplicate code? It's very simple. Take it out!

So we can extract a generic WriteArticle (for easy invocation, we also encapsulate the steps of writing an article into a method):


// global template
public abstract class WriteArticle {

    // Everyone's preface is different, so abstract
    protected abstract void introduction();

    // Everyone's "last" is different, so abstract
    protected abstract void theLast();


    // The actual content to be written is different from each other's "actual content", so abstract.
    protected abstract void actualContent();
    
    // Write a complete article (for easy invocation, we split these steps into a method)
    public final void writeAnCompleteArticle() {

        // Preface
        introduction();

        // Actual content
        actualContent();

        // Last
        theLast();
    }
}

Therefore, 3y template can inherit the common template and realize what you want on the common template.


// 3y article template
public  class Java3yWriteArticle extends WriteArticle {

    // Preface
    @Override
    public void introduction() {
        System.out.println("Only a bald head can grow stronger");
    }

    // Last
    @Override
    public void theLast() {
        System.out.println("Pay attention to my public number: Java3y");

    }
    @Override
    protected void actualContent() {
        System.out.println("Hello, everyone. I'm 3. y,Today I'm going to share with you the template method pattern I've written.");
    }
}

Similarly, 3y girlfriend's article template is similar:


// 3y girlfriend's article template
public  class Java3yGFWriteArticle extends WriteArticle {

    // Preface
    @Override
    public void introduction() {
        System.out.println("balabalabalalabalablablalab");
    }

    // Last
    @Override
    public void theLast() {
        System.out.println("balabalabalalabalablablalab");

    }

    @Override
    protected void actualContent() {
        System.out.println("3y It's a fool. Don't care about him.");
    }
}

It's very convenient when you want to really write an article:


    // 3y writes articles
    public static void main(String[] args) {

        WriteArticle java3ywriteArticle = new Java3yWriteArticle();
        java3ywriteArticle.writeAnCompleteArticle();
    }

    // 3y Girlfriend Writes Articles
    public static void main(String[] args) {
        WriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();
        java3yGFWriteArticle.writeAnCompleteArticle();
    }

Main points:

  • Extract common code, and if the function is uncertain, we modify it as an abstract method.
  • By encapsulating the functions of several fixed steps into a method, exposing the method to the outside world can be very convenient to call.

Well, the above is the template method pattern, so simple!

Introduction of 1.3 Template Method Model

Zen of Design Patterns:

Define an algorithmic framework for an operation and defer some steps to subclasses. The subclass can redefine some steps of the algorithm without changing the structure of the algorithm.

According to our example above, let's talk about the meaning of this passage:

  • Define an algorithmic framework for an operation and defer some steps to subclasses.

    • WriteArticle has a writeAnCompleteArticle() method, which defines all the steps for posting an article, but most of these steps are abstract and have to be implemented by subclasses.
  • Some steps of the algorithm can be redefined without changing the structure of an algorithm.

    • The outside world writes an article by calling the writeAnCompleteArticle() method. If the subclass changes the specific implementation, it will indirectly change the details of the algorithm.

For example, 3y's introduction() in the article template has been changed, "Only when you have enough money can you become stronger"


    @Override
    public void introduction() {
        System.out.println("Only when you have enough money can you become stronger");
    }

We haven't touched the code for writeAnCompleteArticle(), but when we call this method again, the specific implementation changes (because writeAnCompleteArticle is influenced by the specific implementation of the subclass).

Let's take a look at the generic class diagram of the template method pattern:

In the template method pattern, there are also several terms. According to the annotations in our example, I would like to introduce them to you.


// Abstract template class
public abstract class WriteArticle {


    // Basic method
    protected abstract void introduction();

    // Basic method
    protected abstract void theLast();
    
    // Basic method
    protected abstract void actualContent();

    // Template method
    public final void writeAnCompleteArticle() {
        introduction();
        actualContent();
        theLast();
    }
}

// Specific template class
public class Java3yWriteArticle extends WriteArticle {

    // Implementing basic methods
    @Override
    public void introduction() {
        System.out.println("Only when you have enough money can you become stronger");
    }

    // Implementing basic methods
    @Override
    public void theLast() {
        System.out.println("Pay attention to my public number: Java3y");
    }

    // Implementing basic methods
    @Override
    protected void actualContent() {
        System.out.println("Hello, everyone. I'm 3. y,Today I want to share with you the template method pattern I wrote.");
    }
}
  • Basic Method: Implemented in a subclass and called in a template method
  • Template method: Define a framework to call basic methods and complete fixed logic.

Advantages and disadvantages of 1.4 template method

Advantage:

  • Encapsulate the invariant part and expand the variable part. Encapsulate the algorithm that is regarded as the invariant part into the parent class, and the variable part is implemented by the child class!
  • Extract the code of the public part, the behavior is controlled by the parent class, and the subclass is implemented!

Disadvantages:

  • The abstract class defines some abstract methods, which are implemented by subclasses. The results of subclass execution affect the results of the parent class (subclasses affect the parent class), which makes it difficult to read the code!

1.5 Template Method Model JDK Application

The most classic is the AQS (AbstractQueued Synchronizer) under the JUC package. What is AQS?

AQS is actually a framework that allows us to implement locks. The key to internal implementation is the first-in-first-out queue and state state

Let's take a look at acquire() defined by AQS.


    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    

acquire() is equivalent to template method and tryAcquire(arg) is equivalent to basic method.

Last

The template method pattern is also simple. An abstract class has basic methods (methods waiting to be implemented by subclasses), template methods (exposing, calling basic methods, defining the framework of the algorithm), and that's all.

Recommended reading and reference materials:

Java Technologies Public Number: Java3y for Sharing and Exporting Dry Goods. Attention can get a huge amount of video resources!

Brilliant review:

I think my article is well written, you might as well point out the praise!

Topics: Java github JDK