Category: Behavioral design patterns

Purpose: To separate the same type of code so that users who need to use this part of the code can use it on demand

A typical scenario

Apply different compression algorithms and filters to images uploaded by users

Compression algorithm:

  1. Jpeg format
  2. PNG format

Filter:

  1. BlackAndWhite filter
  2. BackgroundBlur filter

Hard coded

public class HardCode {
    public static void main(String[] args) {
        var fileName = "test.jpg";
        var compressor = "jpeg";
        var filter = "blackAndWhite";

        handleUpload(fileName, compressor, filter);
    }

    public static void handleUpload(String fileName, String compressor, String filter)
    {
        if (compressor.equals("jpeg")) {
            System.out.println("Apply the JPEG compression algorithm...");
        } else if (compressor.equals("png")) {
            System.out.println("Apply PNG compression algorithm...");
        }

        if (filter.equals("blackAndWhite")) {
            System.out.println("Apply the blackAndWhite filter");
        } else if (filter.equals("backgroundBlur")) {
            System.out.println("Apply the blackAndBlur filter"); }}}Copy the code

Pattern implementation

code

Define interfaces according to code categories

The above code is divided into two classes, one is the compression algorithm, the other is the filter algorithm

Compression algorithm interface

public interface Compressor {
  void apply(String fileName);
}
Copy the code

The concrete realization of two compression algorithms

public class JpegCompressor implements Compressor {
  @Override
  public void apply(String fileName) {
      System.out.println("Apply the JPEG compression algorithm..."); }}public class PngCompressor implements Compressor {
  @Override
  public void apply(String fileName) {
      System.out.println("Apply PNG compression algorithm..."); }}Copy the code

Filter algorithm

public interface Filter {
  void apply(String fileName);
}
Copy the code

Two filter algorithm concrete implementation

public class BlackAndWhiteFilter implements Filter {
  @Override
  public void apply(String fileName) {
      System.out.println("Apply the blackAndWhite filter"); }}public class BackgroundBlurFilter implements Filter {
    @Override
    public void apply(String fileName) {
        System.out.println("Apply the backgroundBur filter"); }}Copy the code

Use policies

    public static void main(String[] args) {
        var fileName = "test.jpg";
        var compressor = new JpegCompressor();
        var filter = new BlackAndWhiteFilter();

        handleUpload(fileName, compressor, filter);
    }

    public static void handleUpload(String fileName, Compressor compressor, Filter filter) {
        compressor.apply(fileName);

        filter.apply(fileName);
    }
Copy the code

UML

Why is the strategic model better

It can be seen that this policy pattern separates the specific algorithm implementation into separate classes, making the caller flow clearer and the specific algorithm implementation class easier to reuse

A couple of points to note

The specific implementation of each policy can be complex, and encapsulation keeps this part of the complex code separate

The policy object is created by the user and passed to the handler: handleUpload(String fileName, Compressor Compressor, Filter Filter)

The resources

  1. Java-design-patterns.com/patterns/st…
  2. docs.staruml.io/