Design Pattern Strategy Pattern: Make your code flexible to respond to different algorithms | JD Cloud Technology Team

As programmers, we are often faced with the need to choose different algorithms to solve problems in different situations. In this case, the Strategy pattern is a very useful design pattern. In this article, I will introduce you to the concept, structure and how to apply this pattern to make your code more flexible.

1. What is the strategy pattern?

Strategy pattern is a behavioral design pattern that allows the behavior of an algorithm to be selected based on different situations at runtime. This means that we can encapsulate different algorithms into different strategy classes and call these strategies through a unified interface.

2. Structure of Strategy Pattern

Strategy mode includes the following roles:

Context: Holds a reference to a strategy object and calls methods on the strategy object when needed. Context can select different strategies depending on the specific situation.

Strategy: Defines a public interface for encapsulating different algorithms. This interface usually has only one method, which is the method that executes the algorithm.

ConcreteStrategy: implements the strategy interface and provides specific algorithm implementation. Each specific strategy class represents a specific algorithm.

The key to the strategy pattern is that the context holds a reference to a strategy object and executes specific algorithms by calling methods on the strategy object. This approach makes the context very flexible and the algorithm can be switched at runtime according to different needs.

3. Application scenarios of strategy pattern

Strategy pattern is suitable for the following situations:

  • The Strategy pattern can be used when an algorithm implementation needs to be chosen dynamically at runtime.
  • The Strategy pattern provides an elegant solution when a class has multiple behavioral variants and these behaviors can be switched flexibly.

Example (1) For example, in an e-commerce website, we may need to pay for the items in the shopping cart according to different payment methods. It can be a credit card, or of course it can be JD payment, Alipay payment, etc. At this time, we can encapsulate each payment behavior into a specific strategy class, and then select the appropriate payment method for payment through the context.

Maybe you may have seen similar code

if(payType==CreditCardType){
     System.out.println("使用信用卡支付:" + amount + " 元"); 
     // 实现具体的信用卡支付逻辑
}else if(payType==jdPayType){
     System.out.println("使用京东支付:" + amount + " 元"); 
     // 实现具体的京东支付逻辑
}else if(payType==alipayType){
    System.out.println("使用支付宝支付:" + amount + " 元"); 
    // 实现具体的支付宝支付逻辑 
}else{
    System.out.println("没实现,白嫖叭"); 
}

Okay, now I took a look at WeChat and saw why WeChat Pay was not added. I quickly supported it. The R&D brother worked overtime and modified the logic as follows:

if(payType==creditCardType){
     System.out.println("使用信用卡支付:" + amount + " 元"); 
     // 实现具体的信用卡支付逻辑
}else if(payType==jdPayType){
     System.out.println("使用京东支付:" + amount + " 元"); 
     // 实现具体的京东支付逻辑
}else if(payType==alipayType){
    System.out.println("使用支付宝支付:" + amount + " 元"); 
    // 实现具体的支付宝支付逻辑 
}else if(payType==wxPayType){ 
    System.out.println("使用微信支付:" + amount + " 元"); 
    // 实现具体的微信支付逻辑 
}else{
    System.out.println("没实现,白嫖叭"); 
}

After the code is modified, it looks very clear and clear, but there is a problem. If there are other payment methods such as Douyin payment and messy payment in the future, we will have to keep modifying this class and keep adding...else if...

It obviously violates two of the six principles of object-oriented design: single responsibility, open-closed principle (open for extension, closed for modification) . If two of the six are violated, this job will be impossible!

The following demonstrates how to use the strategy pattern to implement different payment methods:

// 定义一个支付的策略接口
public interface PaymentStrategy {
    //这只是个测试场景,真实场景下应该没人用double类型叭
    void pay(double amount);
}

// 具体策略实现
// 信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用信用卡支付:" + amount + " 元");
        // 实现具体的信用卡支付逻辑
    }
}
// 京东支付
public class JdPaymentStrategy implements PaymentStrategy {
    public void pay(double amount) {
       System.out.println("使用京东支付:" + amount + " 元"); 
       // 实现具体的京东支付逻辑
    }
}
//省略...
// 支付宝支付
// 微信支付


// 上下文
public class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(double amount) {
        // 调用策略对象的支付方法
        paymentStrategy.pay(amount);
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        
        // 设置使用信用卡支付策略
        cart.setPaymentStrategy(new CreditCardPaymentStrategy());
        cart.checkout(1000.00);

        // 设置使用jd支付策略
        cart.setPaymentStrategy(new JdPaymentStrategy());
        cart.checkout(2000.00);
        //如果还想用其他支付 就继续写啊
       
    }
}

In the above example, PaymentStrategy is the strategy interface, and CreditCardPaymentStrategy and PayPalPaymentStrategy are specific strategy implementations. ShoppingCart is the context. It sets different payment strategies through the setPaymentStrategy method and calls the payment method of the specific strategy through the checkout method. See if it can be extended to add payment methods. Each subclass only implements a specific payment strategy.

Example (2) Implement a simple calculator (integer). Just think about it and it may involve the following calculation methods: addition, subtraction, multiplication and division. Maybe someone can implement it like this, but I think it must not be you. If you are smart, you should have learned it. Application of strategy pattern in this scenario

Imagine if I want to add a remainder operation?


int num1 = 10;
int num2 = 5;
String operator = "+";

if (operator.equals("+")) {
    int result = num1 + num2;
    System.out.println("加法结果:" + result);
} else if (operator.equals("-")) {
     int result = num1 - num2;
      System.out.println("减法结果:" + result);
} else if (operator.equals("*")) {
     int result = num1 * num2;
     System.out.println("乘法结果:" + result);
} else if (operator.equals("/")) {
     if (num2 != 0) {
          int result = num1 / num2;
          System.out.println("除法结果:" + result);
     } else {
          System.out.println("除数不能为零");
     }
 } else {
     System.out.println("无效的运算符");
 }


4. Summary

Strategy pattern is a flexible and extensible design pattern that implements different behavior variants by encapsulating algorithms into strategy classes. Using the strategy pattern can improve the maintainability and reusability of the code, and also conforms to the principles of object-oriented design.

I hope the introduction in this article will be helpful to your understanding of the strategy pattern, and I hope you can apply this powerful design pattern in actual projects!

Author: JD Retail Yan Xiandong

Source: JD Cloud Developer Community Please indicate the source when reprinting

Lei Jun: The official version of Xiaomi's new operating system ThePaper OS has been packaged. The pop-up window on the lottery page of Gome App insults its founder. Ubuntu 23.10 is officially released. You might as well take advantage of Friday to upgrade! Ubuntu 23.10 release episode: The ISO image was urgently "recalled" due to containing hate speech. A 23-year-old PhD student fixed the 22-year-old "ghost bug" in Firefox. RustDesk remote desktop 1.2.3 was released, enhanced Wayland to support TiDB 7.4 Release: Official Compatible with MySQL 8.0. After unplugging the Logitech USB receiver, the Linux kernel crashed. The master used Scratch to rub the RISC-V simulator and successfully ran the Linux kernel. JetBrains launched Writerside, a tool for creating technical documents.
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/10119716