Zhuge Liang's tips and tricks turned out to be the famous Java design pattern: strategy pattern

Application scenarios

JD.com, Tmall Double Eleven, Valentine's Day merchandise sales, various merchandise have different promotions

  • Full reduction: Full 200 minus 50
  • Every full deduction: every full 100 minus 10
  • Discount: 20% off for two items, 30% off for three items
  • Quantity minus: full three pieces minus the lowest price one

Customers can choose several of them to chop their hands when placing an order. How can the back-end deal with the calculation of the amount flexibly? There may be more promotions on different festivals in the future. How to calculate the amount of the order?

Simple implementation example

public class OrderService {
    
    
    public Order OrderPrices(Order order, String promotion) {
    
    
        if (promotion.equals("promotion-1")) {
    
    
                //计算金额
        } else if (promotion.equals("promotion-2")) {
    
    
                //计算金额
        }

        switch (promotion) {
    
    
            case "promotion-1" :
                //计算金额
                break;
            case "promotion-2" :
                //计算金额
                break;
        }
        return order;
    }
}

There is no problem with using if else or switch case as mentioned above, but there will be many kinds of promotional activities. In this case, there will be a lot of content in if else or switch case, so how to improve it
may be thought of, each The promotion method will be better if it is taken out separately, based on the design principle of this method: the principle of single responsibility

public class OrderService {
    
    
    public Order OrderPrices(Order order, String promotion) {
    
    
        if (promotion.equals("promotion-1")) {
    
    
            calPromotion1(order);
        } else if (promotion.equals("promotion-2")) {
    
    
            calPromotion2(order);
        }

        switch (promotion) {
    
    
            case "promotion-1" :
                calPromotion1(order);
                break;
            case "promotion-2" :
                calPromotion2(order);
                break;
        }
        return order;
    }

    public Order calPromotion1(Order order) {
    
    
        return order;
    }

    public Order calPromotion2(Order order) {
    
    
        return order;
    }
}

Although the above improvement is better, the promotion activities are constantly changing, and the OrderService class needs to be modified as soon as the change is made. The OrderService class is about orders and hopes to be changed less. What is constantly changing is the
analysis of the promotion algorithm . What has changed here is a different algorithm for the same behavior, so improve it again

Improve the code

To implement different algorithms for the same behavior, we can use interfaces to define behaviors, and different algorithms to implement interfaces separately.
Design principle: closed for modification, open for extension

public interface PromotionAlgorithm {
    
    
    Order promotionAlgorithm(Order order);
}
public class PromotionAlgorithm1 implements PromotionAlgorithm {
    
    
    @Override
    public Order promotionAlgorithm(Order order) {
    
    
        System.out.println("满200减50");
        return order;
    }
}
public class PromotionAlgorithm2 implements PromotionAlgorithm {
    
    
    @Override
    public Order promotionAlgorithm(Order order) {
    
    
        System.out.println("满2件打8折");
        return order;
    }
}
public class OrderService {
    
    
    public Order OrderPrices(Order order, String promotion) {
    
    
        if (promotion.equals("promotion-1")) {
    
    
            return new PromotionAlgorithm1().promotionAlgorithm(order);
        } else if (promotion.equals("promotion-2")) {
    
    
            return new PromotionAlgorithm2().promotionAlgorithm(order);
        }

        switch (promotion) {
    
    
            case "promotion-1" :
                return new PromotionAlgorithm1().promotionAlgorithm(order);
            case "promotion-2" :
                return new PromotionAlgorithm2().promotionAlgorithm(order);
        }
        return order;
    }
}

Implement each promotion algorithm separately and then use it. This is the application
class diagram of the strategy pattern :
Insert picture description here

Strategy mode

definition

The strategy mode defines a series of algorithms, and encapsulates each algorithm, and allows them to be replaced with each other, so that the algorithm can change independently of the users who use it.

intention

Define a series of algorithms, encapsulate them one by one, and make them interchangeable

Mainly solve the problem

In the case of multiple similar algorithms, the use of if...else is complicated and difficult to maintain

When to use

A system has many classes, and what distinguishes them is their direct behavior

Pros and cons

advantage:
1: Various algorithms can be switched at will
2: Can avoid the trouble caused by the use of multiple judgments
3: Good scalability

Disadvantages:
1: There are more strategy classes.
2: All strategy classes need to be exposed to the outside world.
Let’s look at the class diagram below:
Insert picture description here
the roles involved:

  1. Context role: holding a reference to the Stratogy class
  2. Abstract strategy (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 strategy class
  3. Specific strategy (ConcreteStartegy) role: packaging related algorithms or behaviors

Context class:

public class Context {
    
    

    private Strategy strategy;

    /** 策略方法 */
    public void contextInterface() {
    
    
        strategy.strategyInterface();
    }
}

Strategy class:

public interface Strategy {
    
    
    /** 策略方法 */
    void strategyInterface();
}

ConcreteStrategy class:

public class ConcreteStrategy implements Strategy{
    
    

    /** 策略方法 */
    @Override
    public void strategyInterface() {
    
    
        //do something
    }
}

Zhuge Liang's Tips

Back then, when Zhao Yun protected Liu Bei from entering the country of Wu to marry a beautiful woman, Zhuge Liang gave him three tips with three tricks, and asked Zhao Yun to act according to the situation. These three tips and tricks are in line with the strategy mode. It seems that Zhuge Liang is not the initiator of the strategy mode but also the original practitioner. The following is a small example: the
Insert picture description here
tips and tricks interface:

public interface SeminalVesicle {
    
    

    /** 按计行事 */
    String tricks();
}

Do according to plan implementation class:

public class BackDoor implements SeminalVesicle {
    
    
    /** 按计行事 */
    @Override
    public String tricks() {
    
    
        return "走乔国老的后门";
    }
}
public class GoBack implements SeminalVesicle {
    
    
    /** 按计行事 */
    @Override
    public String tricks() {
    
    
        return "骗刘备回去";
    }
}
public class Retreat implements SeminalVesicle {
    
    
    /** 按计行事 */
    @Override
    public String tricks() {
    
    
        return "请孙夫人退兵";
    }
}

Zhao Yun class:

public class ZhaoYun {
    
    

    private SeminalVesicle seminalVesicle;

    public ZhaoYun(SeminalVesicle seminalVesicle) {
    
    
        this.seminalVesicle = seminalVesicle;
    }

    /** 按计行事 */
    public String act() {
    
    
        return seminalVesicle.tricks();
    }
}

Test category:

public class Test {
    
    

    public static void main(String[] args) {
    
    
        ZhaoYun zhaoYun = new ZhaoYun(new Retreat());
        System.out.println("赵云按计行事");
        System.out.println(zhaoYun.act());
    }
}

Class diagram: It
Insert picture description here
should be noted that if there are more strategies, almost more than 4, you need to consider using mixed mode to avoid strategy expansion

Guess you like

Origin blog.csdn.net/qq_34365173/article/details/108044954