Design Pattern — Strategic pattern

Define a set of algorithms, encapsulate each algorithm, and make them interchangeable with each other.

Let’s start with a small example and slowly introduce the strategy pattern. For example, when we first learned Java, we always wanted to make a calculator, simple addition, subtraction, multiplication and division. Now we only consider simple addition and subtraction of two numbers. There are many ways to do this, but the following code should be the first thing that comes to mind when we start learning.

class Calculator{
    
    private final static String ADD = "+";
    private final static String SUB = "-";
    
    public int exec(int a, int b,String symbol){
        int result = 0;
        if (ADD.equals(symbol)){
            result = add(a,b);
        }else if (SUB.equals(symbol)){
            result = sub(a,b);
        }
        return result;
    }
    
    private int add(int a,int b){
        return a+b;
    }

    private int sub(int a,int b){
        returna-b; }}Copy the code

At this point we want to optimize the code, because based on the above definition of the policy pattern, we can abstract away the fact that both add and sub methods are algorithms.

interface Calculator{

    public int exec(int a,int b); } // add class AddCalculator implements Calculator{@override public intexec(int a, int b) {
        returna+b; } // SubCalculator implements Calculator{@override public intexec(int a, int b) {
        returna-b; }}Copy the code

By definition we’ve wrapped both addition and subtraction, so what does it mean to make them interchangeable? In fact, according to the incoming different algorithms to execute the corresponding different methods, so according to this to define a middleman for transformation.

class Context{
    
    private Calculator calculator = null;
    
    public Context(Calculator calculator){
        this.calculator = calculator;
    }
    
    public int exec(int a, int b){
        returnthis.calculator.exec(a,b); }}Copy the code

In this way, the conversion of different algorithms can be used.

Context context = null; context = new Context(new AddCalculator()); System. The out. Println (context. The exec (3, 2)); context = new Context(new SubCalculator()); System. The out. Println (context. The exec (3, 2));Copy the code

Then the class diagram of the policy pattern can also be inferred from this.

There are three characters on it

  • Strategy: Abstract Strategy pattern. It defines the definition to be implemented for each specific policy class.
  • ConcreteStrategy: Concrete operations.
  • Context: Passes in a specific policy class that executes different methods.

The strategy pattern is so simple, it is the adoption of object-oriented inheritance and polymorphism mechanism. Nothing else.

In fact, the above addition and subtraction method we can further optimize, here put forward the strategy enumeration.

enum Calculator {

    ADD("+") {
        @Override
        public int exec(int a, int b) {
            return a + b;
        }
    }, 
    SUB("-") {
        @Override
        public int exec(int a, int b) {
            returna - b; }}; String value ="";

    private Calculator(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public abstract int exec(int a, int b);
}

Copy the code

It’s even easier if we call it again.

System. The out. Println (Calculator. The ADD. The exec (3, 2)); System. The out. Println (Calculator. SUB. The exec (3, 2));Copy the code

Why is the above code called policy enumerating you? Enumeration is fine because it is an Enum class, so why a policy? See if you can find any sign of strategy in it. Yes we define an abstract exec method. The implementation is then implemented in each enumeration member. This is the same as the policy pattern definition, encapsulation of the algorithm has its own implementation, and can be switched.

Note: Policy enumerations are an excellent and convenient pattern, but they are limited by the type of enumerations. Each enumerator is public, final, static, and extensibility is limited, so policy enumerations generally play an infrequent role in development.

reference

  • Zen of design patterns
  • www.cnblogs.com/java-my-lif…