Describes the use of template patterns and policy patterns, and the differences between the two, based on Java.

Lou elder brother, see you write article everyday, feel very boring, want to tell us a joke first. “Well, what is it? Let me think…”

A reporter went to the South Pole to interview a group of penguins. He asked the first penguin, “What do you do every day?”

The penguin says, “Eat, sleep, play Peas!”

Then ask the 2nd penguin again, that penguin still say: “eat, sleep, dozen beans beans!”

Puzzled, the reporter asked the other penguins the same answer, and so on, 99 penguins.

When he got to the 100th chick, the reporter went over and asked: What do you do every day?

The penguin answers, “Eat and sleep.”

Remember the surprise of ask again: “why don’t you dozen dou dou?”

Small penguin skimming mouth, stared at a reporter said: “I am dou Dou!”

When I first saw this joke, I felt it was both simple and funny, so I got the inspiration for the following article.

The Low way

Suppose there are three penguins, all of whom like to “eat, sleep, and fight peas” :

public class littlePenguin {

    public void everyDay(a) {

        System.out.println("Eat");

        System.out.println("Sleep");

        System.out.println("Beat the peas with their little wings.");

    }

}

public class middlePenguin {

    public void everyDay(a) {

        System.out.println("Eat");

        System.out.println("Sleep");

        System.out.println("Beat a bean with a round belly.");

    }

}

public class bigPenguin {

    public void everyDay(a) {

        System.out.println("Eat");

        System.out.println("Sleep");

        System.out.println("Take a feather duster and beat the peas.");

    }

}

public class test {

    public static void main(String[] args) {

        System.out.println("littlePenguin:");

        littlePenguin penguin_1 = new littlePenguin();

        penguin_1.everyDay();

        

        System.out.println("middlePenguin:");

        middlePenguin penguin_2 = new middlePenguin();

        penguin_2.everyDay();

        

        System.out.println("bigPenguin:");

        bigPenguin penguin_3 = new bigPenguin();

        penguin_3.everyDay();

    }

}

Copy the code

Take a look at the result:

littlePenguin:

Have a meal

Go to bed

Beat the peas with their small wings

middlePenguin:

Have a meal

Go to bed

Beat the beans with the round belly

bigPenguin:

Have a meal

Go to bed

Beat the peas with a feather duster

Copy the code

This is the easiest way for you to use when you’re writing code, it’s easy to get started, it’s easy to understand, and when you look at the old code in your project, you often find it, so let’s see how you can refactor it step by step.

The conventional way

In fact, “eating, sleeping and playing beans” are all independent behaviors. In order not to affect each other (such as falling asleep suddenly while eating, or rushing to play beans when not sleeping well, just kidding), we can encapsulate them simply through functions:

public class littlePenguin {

    public void eating(a) {

        System.out.println("Eat");

    }

    public void sleeping(a) {

        System.out.println("Sleep");

    }

    public void beating(a) {

        System.out.println("Beat the peas with their little wings.");

    }

}

public class middlePenguin {

    public void eating(a) {

        System.out.println("Eat");

    }

    public void sleeping(a) {

        System.out.println("Sleep");

    }

    public void beating(a) {

        System.out.println("Beat a bean with a round belly.");

    }

}

// bigPenguin same, omit...

public class test {

    public static void main(String[] args) {

        System.out.println("littlePenguin:");

        littlePenguin penguin_1 = new littlePenguin();

        penguin_1.eating();

        penguin_1.sleeping();

        penguin_1.beating();

        //...

    }

}

Copy the code

Does that make it a little bit clearer, if you’ve been working for a while, you might want to implement it this way, but do we have a more elegant way of doing it?

Template pattern

In Template Pattern, an abstract class exposes a method/Template that executes its methods. Its subclasses can override method implementations as needed, but the calls will be made in the manner defined in the abstract class. This type of design pattern is behavioral.

This three penguins, because every day to eat, sleep and sleep standing up, but play doug way is different, so we can “have a meal, sleep, play,” doug abstracting, because “have a meal, sleep” are all the same, so we can direct implementation, but they “doug” in different ways, so the encapsulated into abstract method, It takes each penguin individually to achieve the “beating beanie” method. Finally, add a method called everyDay() to fix the routine:

public abstract class penguin {

    public void eating(a) {

        System.out.println("Eat");

    }

    public void sleeping(a) {

        System.out.println("Sleep");

    }

    public abstract void beating(a);

    public void everyDay(a) {

        this.eating();

        this.sleeping();

        this.beating();

    }

}

Copy the code

Each penguin achieves its own way of “beating the peas” independently:

public class littlePenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Beat the peas with their little wings.");

    }

}

public class middlePenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Beat a bean with a round belly.");

    }

}

public class bigPenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Take a feather duster and beat the peas.");

    }

}

Copy the code

Finally, how to call:

public class test {

    public static void main(String[] args) {

        System.out.println("littlePenguin:");

        littlePenguin penguin1 = new littlePenguin();

        penguin1.everyDay();

        System.out.println("middlePenguin:");

        middlePenguin penguin2 = new middlePenguin();

        penguin2.everyDay();

        System.out.println("bigPenguin:");

        bigPenguin penguin3 = new bigPenguin();

        penguin3.everyDay();

    }

}

Copy the code

“Lou, you have a hard time looking at this code, can you draw me a UML diagram?”


The strategy pattern

In the Strategy Pattern, the behavior of a class or its algorithm can be changed at run time. This type of design pattern is behavioral. In the policy pattern, we create objects that represent various policies and a context object whose behavior changes as the policy object changes. The policy object changes the execution algorithm of the context object.

Let’s start by abstracting the behavior of three penguins:

public abstract class penguin {

    public void eating(a) {

        System.out.println("Eat");

    }

    public void sleeping(a) {

        System.out.println("Sleep");

    }

    public abstract void beating(a);

}

Copy the code

Each penguin achieves its own way of “beating the peas” independently:

public class littlePenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Beat the peas with their little wings.");

    }

}

public class middlePenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Beat a bean with a round belly.");

    }

}

public class bigPenguin extends penguin {

    @Override

    public void beating(a) {

        System.out.println("Take a feather duster and beat the peas.");

    }

}

Copy the code

We create objects representing various policies and a context object whose behavior changes as the policy object changes. The contex object is:

public class behaviorContext {

    private penguin _penguin;



    public behaviorContext(penguin newPenguin) {

        _penguin = newPenguin;

    }

    public void setPenguin(penguin newPenguin) {

        _penguin = newPenguin;

    }

    public void everyDay(a) {

        _penguin.eating();

        _penguin.sleeping();

        _penguin.beating();

    }

}

Copy the code

Finally, how to call:

public class test {

    public static void main(String[] args) {

        behaviorContext behavior = new behaviorContext(new littlePenguin());

        behavior.everyDay();



        behavior.setPenguin(new middlePenguin());

        behavior.everyDay();



        behavior.setPenguin(new bigPenguin());

        behavior.everyDay();

    }

}

Copy the code

We can specify how everyDay() should be called by passing different objects to the behaviorContext. In fact, my example makes the strategy mode a little complicated, because in pure strategy mode, the three penguins only have different methods of beating(), so it can be understood as different algorithms. The reason why we introduce everyDay() is that it is often used in actual project scenarios. That is, the changing algorithm beating() is packaged into a specific execution process, so the strategy mode looks less intuitive, but the core idea is the same.

Again, the following UML diagram uses the policy mode, because I want to talk about it in combination with a specific business scenario. If you want to see the simplest version of the policy mode, there is no encapsulation of everyDay, only the policy change that performs beating. You can see the rookie tutorial for this.


Template vs. policy mode

When choosing a template pattern and strategy pattern, I found that both can completely meet my needs, and then I go to the online access to a lot of data, hoping to find two modes in the technology choice, tell me what it needs to choose which model can be determined, ashamed to say that, until now I have not found, because online only tell me the difference between the two implementations pose, But there is no explanation of how to specific selection, I will put my collection of information, feel the core part of the list, to give you some reference.

Someone please explain to me what is the difference between the template method pattern and the policy pattern?

As far as I can tell they are 99% the same – the only difference is that the template method pattern has abstract classes as base classes, while the strategy classes use interfaces implemented by each concrete strategy class.

However, as far as customers are concerned, they consume in exactly the same way — is that right?

The main difference between the two is the select of the specific algorithm.

Occurs at compile time by subclassing the Template method pattern. Each subclass provides a different concrete algorithm by implementing an abstract method of the template. When the client calls the methods of the template’s external interface, the template calls its abstract methods (its internal interface) as needed to invoke the algorithm.

In contrast, the policy pattern allows selectalgorithm by containment at run time. Concrete algorithms are implemented through separate classes or functions that pass as parameters to constructors or constructors. For this parameter select which algorithm changes depending on the state of the program or inputDynamic.

To sum up:

  • Template method pattern: AlgorithmSelect compilation time by subclassing
  • Strategy pattern: By curbing runtime AlgorithmSelect

The above is a complete copy of the difference on the Internet, only see the difference between the realization of posture, but if this can guide me to choose the type, I think it is not enough, the following may be more specific:


Similar:

  • Both policy and template method patterns can be used to satisfy the open closed principle, making it easy for software modules to expand without changing the code.

  • Both patterns represent the separation of a generic function from a detailed implementation of that function. However, there are some differences in the granularity they provide.

Differences:

  • In a policy, the coupling between the client and the policy is looser, whereas in a template approach, the two modules are more tightly coupled.

  • While an abstract class can be used on a case-by-case basis in a policy, most use an interface instead of a concrete class, and most use an abstract or concrete class instead of an interface in the Template method.

  • In the Strategy pattern, the overall behavior of a class is generally represented by an interface. On the other hand, the Template method is used to reduce less code duplication, and boilerplate code is defined in the base framework or abstract class. In Template Method, you can even have a concrete class with a default implementation.

  • In short, you can change the entire policy (algorithm) in the policy pattern, but in the Template pattern, only some things change (part of the algorithm), while the rest of the events remain the same. In Template Method, invariant steps are implemented in an abstract base class, while variant steps are either implemented by default or not implemented at all. In the Template method, the component invokes enforce the steps and the sorting of the steps required by the algorithm, but allows the component client to extend or replace certain steps.

Seeing the above summary, I still feel that it does not answer my question. Finally, I will quote a paragraph of different interpretation on the Internet:

Template mode:

  • It’s based on inheritance.

  • Defines the skeleton of an algorithm that cannot be changed by subclasses. Only certain operations can be overridden in subclasses.

  • The parent class completely controls the algorithm, distinguishing only the specific step from the specific class.

  • Binding is done at compile time.

Strategy mode:

  • It’s based on authorization/composition.

  • It changes the contents of the object by modifying the behavior of the method.

  • It is used to switch between algorithm families.

  • It changes the behavior of an object at run time by completely replacing an algorithm with another algorithm at run time.

  • The binding is done at run time.

For me with obsessive-compulsive disorder, without finding the root of the problem, I always feel something is wrong. Let me tell you my understanding of the difference between the two. To be honest, I can only see a difference in the implementation posture between the two design patterns. I don’t agree with the policy pattern that defines a common interface and the template pattern that doesn’t, because I sometimes define a common interface for the template pattern. Then some people say that the policy pattern needs to define a bunch of objects, the template pattern does not need, if there are 10 different penguins, template pattern also needs to define 10 different penguin classes, and then specifically for a specific method to implement?

Say so, these two kinds of design patterns, I don’t feel to the binary classification, is how great is how I use, such as I don’t need a fixed execution process, such as only go to dozen doug, only need to do to a method for concrete abstract, I would like to choose the strategy pattern, because of this I feel I need to use the object, the more clear. If I have a fixed execution process, such as “eat, sleep, play beans”, I prefer to use the template method, probably because I have seen too much code, but also used to see, more willing to use the template method to standardize the fixed code execution process.

Of course, I also can use A combination of both, we can use A template method, for example, to achieve the three penguins, but for middlePenguin, there may be divided into penguins, penguins A of B, C, they all like the penguin sister next door, but love in A different way, have A crush on, do have A direct, And the bully CEO, I can use strategic mode to dictate how they express themselves to sister Penguin.

Elder brother is so capricious, oneself how use of cool, how come ~~

Afterword.

Because I have been doing business before, so I used to write code basically if… Else, design patterns, although very early know (the 4 people to help during the period of graduate students to see that this “design patterns” for 3 times), but not to write the actual code, all always have a sense of number three in the fog, and then a long time, some model will forget, really meet need to refactor code, or look at the others code, still have to check the data, “oh, This is the original design pattern, the number “. So THIS time I plan to combine the specific business scenarios, the common design patterns are sorted out, mainly because I do not want to be too ambitious, later code refactoring, various design patterns can easily be used, so my purpose has been achieved.

Welcome everyone to like a lot, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point attention, do not get lost ~~