define

The policy pattern belongs to the behavior pattern of 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. The policy pattern allows the algorithm to change without affecting the client.

UML diagrams

  • Context role: Holds a reference to a Strategy, which is ultimately called by the client.
  • Abstract Strategy Role: This 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 role: Encapsulates associated algorithms or behaviors.

The instance

Let’s say we need an image loading framework. We can choose Glide, Fresco, ImageLoader, Picasso. For example, ImageLoader implements image loading. Suddenly one day the Boss asks you to change the loading framework to Glide, if many classes call ImageLoader, then you have to replace them one by one, and replace them to doubt life, if you used strategy mode before, then the replacement process will be very easy.

First, define the corresponding roles:

1. Environmental Roles:

public class Context {

    Strategy strategy;

    private Context// strategy = new GlideStrategy(); // strategy = new PicassoStrategy(); // strategy = new FrescoStrategy(); strategy = new ImageLoaderStrategy(); } public voidloadImage() {
        strategy.showImage();
    }

    public static Context getInstance() {
        returnInnerClass.context; } private static final class InnerClass { private static Context context = new Context(); }}Copy the code

2. Abstract policy roles

public interface Strategy {
    void showImage();
}
Copy the code

3. Specific policy roles

//Glide
public class GlideStrategy implements Strategy{
    @Override
    public void showImage() {
        System.out.println("Glide ShowImage");
    }
}

//Fresco
public class FrescoStrategy implements Strategy {

    @Override
    public void showImage() {
        System.out.println("Fresco ShowImage");
    }
}

//ImageLoader
public class ImageLoaderStrategy implements Strategy {

    @Override
    public void showImage() {
        System.out.println("ImageLoader ShowImage");
    }

}

//Picasso
public class PicassoStrategy implements Strategy {
    @Override
    public void showImage() {
        System.out.println("Picasso ShowImage"); }}Copy the code

The final call can be made directly like this:

Context.getInstance().loadImage();
Copy the code

Which policy role we initialize in the Context’s constructor will then call its methods to load the image, allowing the image-loading framework to change flexibly independently of the caller. Full code address: Policy mode

Advantages and disadvantages of strategic patterns

1, the advantages of

  • The implementation details of specific policies (algorithms) are hidden from the customer, completely independent of each other. Concrete policy classes are implemented from the same interface and can switch between them freely
  • It is easy to extend, and if new policy classes need to be added, there is little need to change existing code
  • Use policy patterns to avoid multiple conditional transition statements. Multiple transfer statement is not easy to maintain, it takes which algorithm or take which behavior of the logic and algorithm or behavior of the logic mixed together, all listed in a multiple transfer statement, than the use of inheritance method is primitive and backward.

2 and disadvantages

  • There is an additional cost associated with maintaining individual policy classes, and it becomes more expensive when there are too many policy classes.
  • The client must know all the policy classes and decide which one to use. This means that the client must know the difference between these algorithms and decide which policy class to use.

Applicable scenario

  • A situation in which several classes share the same main logic but differ slightly in the algorithm and behavior of some of the logic.
  • There are several similar behaviors, or algorithms, and the client needs to dynamically decide which one to use, so the policy pattern can be used to encapsulate these algorithms for the client to invoke.