preface

Recently, I happened to be reconstructing the strategy mode, which provided some material for my blog. Next, I will introduce the strategy mode to you

Definition of policy patterns

Policy pattern: Behavior pattern belonging to an object. The idea is to take a set of algorithms and encapsulate each one into a separate class with a common interface, making them interchangeable.

It is a wrapper around the algorithm (that is, the processing of our business logic), separating the responsibility of using the algorithm from the algorithm itself and delegating it to different object management. Policy patterns typically wrap a set of algorithms into a set of policy classes as a subclass of an abstract policy class. In a word: “Prepare a set of algorithms and encapsulate each algorithm so that they are interchangeable”.

With this definition in mind, let’s look at the common class diagram of the policy pattern:

Context: A Context role that holds a reference to a Strategy.

Strategy: Abstract policy role, which is an abstract role, usually implemented by an interface or abstract class. This role gives all the interfaces required by the specific policy classes

ConcreteStrategy: Concrete policy roles that wrap associated algorithms or behaviors and implement or inherit abstract policy roles.

The functions and responsibilities of these three roles are very clear, the corresponding source code implementation is also very simple, now we will take a quick look at the corresponding universal source code for each role.

With the basic code structure of the policy pattern, it is very simple to use in the client class. If you want a policy, it generates its specific policy object into the context object, and then the context object performs the specific policy operation. The code is as follows:

This is a simple implementation of the policy pattern.

Policy pattern usage scenarios and examples

We often encounter a lot of if/else code blocks

For example, there is a demand for workplace punishment, 100 yuan fine for lateness, 200 yuan fine for working and sleeping. We only have two punishments right now, and as we have more and more punishments, we have more and more judgments here. Resulting in redundant code blocks.

public class WorkPunish {

   public static void main(String[] agrs){
       String state ="late";
       punish(state);
   }
   
   public static void punish(String state){
       if ("late".equals(state)){
           System.out.println("100");
       }else if ("sleep".equals(state)){
           System.out.println("200");
       }  System.out.println("Warning"); }}Copy the code

This is where the strategic pattern comes in. Using the policy pattern helps us to encapsulate each processing logic into a separate class, using the corresponding class for the processing logic that the client class needs to do, and calling its methods that encapsulate the details of the business processing.

Next up is a demo using the policy pattern.

Define for the first time an abstract interface that contains punishment methods

public interface IPunish {
    void exePunish(a);
}
Copy the code

The next step is to write a concrete implementation class that implements the abstract interface, which implements the methods of the abstract class and handles the concrete logic here. Note that we also inherit InitializingBean here. The InitializingBean interface provides a way for the bean to initialize methods. It only includes the afterPropertiesSet method, which any class that inherits this interface will execute when initializing the bean. Will register the object, next to see the implementation of registration ~

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class LatePunish implements IPunish.InitializingBean{
    public void exePunish(a) {
        System.out.println("100");
    }

    @Override
    public void afterPropertiesSet(a) throws Exception {
        PunishFactory.registerPunish("late".this); }}Copy the code

This is a factory class. Register all implementations here at initialization and store them in the map. Select the corresponding implementation object according to the needs of the client to call the specific method.

import java.util.HashMap;
import java.util.Map;
public class PunishFactory {

    private static Map<String,IPunish> punishMap = new HashMap<String,IPunish>();
    private PunishFactory(a) {}
    private static final IPunish EMPTY = new EmptyPunish();
    / / to get
    public static IPunish getPunish(String state) {
        IPunish result = punishMap.get(state);
        return result == null ? EMPTY : result;
    }
    // Register the penalty object here
    public static void registerPunish(String state,IPunish o){
        punishMap.put(state, o);
    }
    private static class EmptyPunish implements IPunish {
        public void exePunish(a) {
            // Empty class}}}Copy the code

Next is a bunch of if/else processing logic after reconstruction. All you need to do is to get the object that you have won the bet according to the corresponding state and call the implementation method to complete the requirements

public class WorkPunish {
    public static void main(String[] agrs){
        String state ="late"; IPunish punish = PunishFactory.getPunish(state); punish.exePunish(); }}Copy the code

This is where our implementation ends, and this is one scenario where the policy pattern is used.

Advantages of the policy pattern

With the policy mode, algorithms or behaviors can be replaced without modifying the original system, and new algorithms or behaviors can be flexibly added, which provides system scalability

The policy pattern provides the management and maintenance of a class of algorithms.

Using policy patterns eliminates the need for multiple conditional judgments, leaving external modules to decide which policy class to enforce.

Disadvantages of the policy pattern

The client must know all the policy classes and decide which one to use.

Many policy classes are created, increasing the number of items in the class.

conclusion

This is the end of the study of the strategic pattern in this paper. Of course, there is much more about the strategic pattern. For example, the article combines the strategic pattern and the factory pattern to reconstruct the code. See you in the next article if you understand the factory model