preface

Only a bald head can be strong.

Welcome to our GitHub repository Star: github.com/ZhongFuChen…

In the last post, a reader said that he finished the facade pattern in a minute, so today’s title is “Learn template Method Pattern in a minute”.

Review the design patterns I wrote earlier:

  • Explain the agency model to your girlfriend
  • The packaging pattern is as simple as that
  • How many ways do you know how to write singleton?
  • Do you understand the factory model?
  • The strategy model is that simple!
  • Three minutes to learn the facade mode!

Design patterns are a must for both job interviews and personal promotion. Today we’ll cover the template method pattern

I. Template method pattern

1.1 Real-world examples of the template method pattern

Everyone knows that every time I write an original technical article, I start with the words “Only a bald head can be strong.” I certainly can’t copy this sentence every time I write an article (because that would be too much trouble).

I have my own writing template to show you:

The preface and the last are fixed, as for the first and second point you have to see what to write, write different articles corresponding content is not the same.

Every time I write an article, I just add what I want to write to this template, so 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, and in the same way I can describe my writing process in code, take a look.

Every 3Y article will have the “preface” and “final” content, 3Y has written out these two modules.


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

    / / the last
    public void theLast(a) {
        System.out.println("Follow my official account: Java3y"); }}Copy the code

When writing an article, 3y might be used like this:


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

        Java3yWriteArticle writeArticle = new Java3yWriteArticle();

        / / introduction
        writeArticle.introduction();

        // The actual content
        System.out.println("Hi, I'm 3Y, and today I'm here to share with you my template method pattern.");

        / / the last
        writeArticle.theLast();
    }


Copy the code

This can complete the function of 3Y writing articles, but is it good? At this time, 3Y’s girlfriend also wants to write an article, and her article also wants to have two modules of “preface” and “last”, so the template of 3Y’s girlfriend’s article is like this:


// 3y girlfriend post template
public  class Java3yGFWriteArticle {

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

    / / the last
    public void theLast(a) {
        System.out.println("balabalabalalabalablablalab"); }}Copy the code

3Y’s girlfriend might also use it like this when writing an article:


    // 3y's girlfriend writes the article
    public static void main(String[] args) {
        Java3yGFWriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();

        / / introduction
        java3yGFWriteArticle.introduction();

        // The actual content
        System.out.println("3Y's an idiot. Leave him alone.");

        / / the last
        java3yGFWriteArticle.theLast();

    }
Copy the code

It can be found that 3y and 3y’s girlfriend call introduction() repeatedly when they want to write an article; And theLast (); . Moreover, the “preface” and “end” in 3y’s article template and 3y’s girlfriend’s article template are only different implementations, but they are defined twice, which is obviously duplicate code. What do we do with repetitive code? It’s simple, extract it!

We can then extract a generic WriteArticle(we also encapsulate the step of writing the article as a method for ease of call) :


// Generic template
public abstract class WriteArticle {

    // Everyone's preface is different.
    protected abstract void introduction(a);

    // Everyone's "end" is different.
    protected abstract void theLast(a);


    // The actual content is different from each other.
    protected abstract void actualContent(a);
    
    // Write a complete article (for ease of calling, we split these steps into a method)
    public final void writeAnCompleteArticle(a) {

        / / introduction
        introduction();

        // The actual content
        actualContent();

        / / the lasttheLast(); }}Copy the code

So, 3y’s template can inherit from the generic template, and implement what you want on the generic template:


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

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

    / / the last
    @Override
    public void theLast(a) {
        System.out.println("Follow my official account: Java3y");

    }
    @Override
    protected void actualContent(a) {
        System.out.println("Hi, I'm 3Y, and today I'm here to share with you my template method pattern."); }}Copy the code

Similarly, 3Y’s girlfriend’s article template is similar:


// 3y girlfriend post template
public  class Java3yGFWriteArticle extends WriteArticle {

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

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

    }

    @Override
    protected void actualContent(a) {
        System.out.println("3Y's an idiot. Leave him alone."); }}Copy the code

This comes in handy when you want to actually write an article:


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

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

	// 3y's girlfriend writes the article
    public static void main(String[] args) {
        WriteArticle java3yGFWriteArticle = new Java3yGFWriteArticle();
        java3yGFWriteArticle.writeAnCompleteArticle();
    }
Copy the code

Key points:

  • Extract the common code, and if the functionality is undefined, dress it up as an abstract method.
  • Encapsulate the functionality of several fixed steps into a method, expose the method, and make it very easy to call.

Well, the above is the template method pattern, simple as that!

1.3 Introduction to template Methods

Zen of Design Patterns:

Define an algorithm framework in an operation, deferring some steps to subclasses. Enables subclasses to redefine certain steps of an algorithm without changing its structure.

Let’s talk about what this means based on our example above:

  • Define an algorithm framework in an operation, deferring some steps to subclasses.
    • WriteArticle has a method called writeAnCompleteArticle() that defines all the steps for Posting an article, but these steps are mostly abstract and must be implemented by subclasses.
  • Enables subclasses to redefine certain steps of an algorithm without changing its structure
    • The outside world writes the article by calling the writeAnCompleteArticle() method, and subclasses indirectly change the details of the algorithm by changing the implementation.

For example, the introduction() of 3Y in the article template has been changed, “Only with money can we become stronger”.


	@Override
    public void introduction(a) {
        System.out.println("Only with money can we become strong.");
    }

Copy the code

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

Let’s look at the generic class diagram for the template method pattern:

There are also a few terms in the template method pattern, which I’ll introduce to you based on the comments in our example:


// Abstract template class
public abstract class WriteArticle {


    // Basic method
    protected abstract void introduction(a);

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

    // Template method
    public final void writeAnCompleteArticle(a) { introduction(); actualContent(); theLast(); }}// Specify a template class
public class Java3yWriteArticle extends WriteArticle {

    // Implement the basic method
    @Override
    public void introduction(a) {
        System.out.println("Only with money can we become strong.");
    }

    // Implement the basic method
    @Override
    public void theLast(a) {
        System.out.println("Follow my official account: Java3y");
    }

    // Implement the basic method
    @Override
    protected void actualContent(a) {
        System.out.println("Hi, I'm 3Y, and today I'm here to share with you my template method pattern."); }}Copy the code
  • Base methods: implemented in subclasses and called in template methods
  • Template methods: Define a framework to implement calls to basic methods, complete with fixed logic.

1.4 Advantages and disadvantages of the template approach

Advantages:

  • Encapsulate what does not change and extend what does change. Encapsulate the algorithm of the invariant part into the parent class, and implement the variable part by the subclass!
  • Extract the common part of the code, behavior controlled by the parent class, subclass implementation!

Disadvantages:

  • Abstract classes define some abstract methods that are implemented by subclasses whose results affect the results of their parent classes, making code difficult to read!

1.5 Template Method Mode JDK Application

The classic is JUC package of AQS (AbstractQueuedSynchronizer). What is AQS?

AQS is basically a framework that allows us to implement locks. The key of internal implementation is: fifO queue, state state

We can look at acquire() as defined by AQS


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

Acquire() is the template method, and tryAcquire(arg) is the base method.

The last

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

Recommended reading and references:

  • Zen of Design Patterns
  • Blog.csdn.net/carson_ho/a…
  • Blog.csdn.net/hguisu/arti…

Happy to share and export dry Java technology public account: Java3y. Pay attention to receive massive video resources!

Highlights:

  • Summary of 2018 [14 Books for free]

Think my article is written well, might as well click a thumbs-up!