Strategy mode is the cornerstone of realizing a variety of marketing methods

Posted by sumeet on Sat, 18 Dec 2021 13:25:26 +0100

Hello everyone, today is cloudy. There are 3816 lightning flashes in Hangzhou. Take a closer look, it originally consists of four big characters: design mode!

Today is another day of design mode. What Hong Jue wants to talk about today is strategy mode.

Policy pattern is a kind of behavioral pattern. This kind of design pattern pays special attention to the communication between objects.

What is the strategic model and when to use it?

For example, when you do a calculation, you may use addition, subtraction, multiplication or division. In the final analysis, addition, subtraction, multiplication and division itself is an algorithm, and the algorithm itself is just a strategy; When you want to travel, walking, cycling, high-speed rail, aircraft, etc. are both a way of travel and a strategy in itself.

When there are such similar algorithms, we abstract these algorithms into a specific execution method, which is implemented and managed by a specific policy class. Then, all policy classes are shielded from internal details by a unified Context, and provide direct access to the algorithm.

After defining a series of algorithms, they can flexibly replace each other, avoid using multiple judgment conditions, and have good expansibility.

However, there are also disadvantages. The corresponding specific policy classes will increase and need to be exposed. Here is an example to explain the benefits of using the policy pattern.

class Calculator {
    public int operation(int op1, int op2, int type) {
        if(type == 1) {
            return op1 + op2;
        } else if(type == 2) {
            return op1 - op2;
        } else if(type == 3) {
            // ....
        } else if(type == 4) {
            // ....
        }
    }
}

If you don't use the policy mode, if you want to implement the calculation, you need to judge the type of calculation multiple times, and then return the corresponding answer. In addition, the calculation method is added later. You also need to modify the original code, which violates the opening and closing principle (open to expansion and close to modification).

So if we use the policy pattern, what will the framework structure be like?

public class Main {
    public static void main(String[] args) throws Exception {
        Context context = new Context(new Add());
        System.out.println(context.executeOperation(1, 2));

        context = new Context(new Sub());
        System.out.println(context.executeOperation(1, 2));

    }
}

interface Calculator {
    int operation(int op1, int op2);
}

class Context {
    Calculator calculator;

    public Context(Calculator calculator) {
        this.calculator = calculator;
    }

    public int executeOperation(int num1, int num2) {
        return calculator.operation(num1, num2);
    }

}

class Add implements Calculator {

    @Override
    public int operation(int op1, int op2) {
        return op1 + op2;
    }
}

class Sub implements Calculator {

    @Override
    public int operation(int op1, int op2) {
        return op1 - op2;
    }
}
/*
3
-1
*/

This is only a relatively simple implementation of the strategy mode. We are now discussing a slightly more complex scenario to deepen everyone's impression. When you buy a commodity in ordinary shopping, you may buy it at the original price, there may be a discount, or return yyy yuan when it is over xxx yuan. These are all marketing activities. In fact, these are also a strategy. So how to implement the policy pattern?

Class diagram

Specific code:

public abstract class Strategy {
    // Specific behaviors (algorithms, marketing activities, etc.)
    public abstract double operation(double money);
}

public class NormalStrategy extends Strategy {
    // original price
    @Override
    public double operation(double money) {
        return money;
    }
}

public class DiscountStrategy extends Strategy {

    // Discount: 10% off by default
    private double discount = 1;

    public DiscountStrategy(double discount) {
        this.discount = discount;
    }

    @Override
    public double operation(double money) {
        return money * discount;
    }
}

public class RefundStrategy extends Strategy {
	// Full lowerLimitMoney return refundMoney
    
    // Rebate conditions
    private double lowerLimitMoney;

    // Return amount
    private double refundMoney;

    public RefundStrategy(double lowerLimitMoney, double refundMoney) {
        this.lowerLimitMoney = lowerLimitMoney;
        this.refundMoney = refundMoney;
    }

    @Override
    public double operation(double money) {
        if(money >= refundMoney) {
            return money - Math.floor(money / lowerLimitMoney) * refundMoney;
        } else {
            return money;
        }
    }
}

public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public double getCash(double money) {
        return strategy.operation(money);
    }

}

public class client {
    public static void main(String[] args) {
        Context context = new Context(new NormalStrategy());

        // Commodity A sells for 100 yuan
        double price = 100;
        System.out.println("100 Normal charge of RMB = " + context.getCash(price));

        // 50% off item A
        context = new Context(new DiscountStrategy(0.5));
        System.out.println("100 Charge after 50% discount = " + context.getCash(price));

        // Purchase quantity
        int num = 5;
        // Return 100 at 400
        context = new Context(new RefundStrategy(400, 100));
        System.out.println("Return to 100 activities after 400,  Bought" + num + "piece, Each piece" + price + "element, Current charge = " + context.getCash(num * price));
    }
}
/*
100 Normal charge for goods = 100.0 yuan
100 50.0 yuan after 50% discount
 For the activity of returning 100 after 400, you have purchased 5 pieces, each of which is 100.0 yuan, and the current charge = 400.0 yuan
*/

We can conclude that if a system has many classes and the difference lies only in their different behaviors, one of them can be dynamically selected by using the policy pattern.

Well, this article is so much, I hope it will help you!

I hope everyone can read the article with a skeptical attitude and explore the principle.

The road is blocked and long. The past is a preface and the future is a chapter.

Look forward to our next meeting!

Topics: Python Java Algorithm Back-end Programmer