策略模式

     +------------------+
     |      Context     |
     +------------------+
     | - strategy:Strategy |
     +------------------+
     | + setStrategy(Strategy): void |
     | + executeStrategy(): void     |
     +------------------+
                  |
                  | uses
                  v
       +------------------+
       |    Strategy      |
       +------------------+
       | + execute(): void|
       +------------------+
                  ^
                  |
        +---------+----------+
        |                    |
+---------------+    +---------------+
| ConcreteStrategyA |    | ConcreteStrategyB |
+------------------+    +------------------+
| + execute(): void |    | + execute(): void |
+------------------+    +------------------+

策略模式示例

策略接口

public interface Strategy {
    void execute();
}

具体策略类

public class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing Strategy A");
    }
}


public class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("Executing Strategy B");
    }
}

上下文类

public class Context {
    private Strategy strategy;

    // 设置策略
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    // 执行策略
    public void executeStrategy() {
        strategy.execute();
    }
}

使用

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

        // 使用策略A
        context.setStrategy(new ConcreteStrategyA());
        context.executeStrategy();  // 输出: Executing Strategy A

        // 使用策略B
        context.setStrategy(new ConcreteStrategyB());
        context.executeStrategy();  // 输出: Executing Strategy B
    }
}

策略模式+工厂模式

主要是通过type获取具体的策略模式,这是一种映射关系Mapping

//策略工厂类
public class PaymentStrategyFactory {

    private static final Map<String, PaymentStrategy> strategies = new HashMap<>();

    //静态代码块进行 映射关系的初始化
    static {
        strategies.put("creditcard", new CreditCardPayment());
        strategies.put("paypal", new PayPalPayment());
        strategies.put("bitcoin", new BitcoinPayment());
    }
	
    //获取相应策略的策略实现类
    public static PaymentStrategy getStrategy(String type) {
        return strategies.get(type.toLowerCase());
    }
}

客户端

public class Main {
    public static void main(String[] args) {
        PaymentStrategyFactory factory = new PaymentStrategyFactory();

        // 获取并使用信用卡支付策略
        PaymentStrategy strategy = factory.getStrategy("creditcard");
        strategy.pay(100);

        // 获取并使用PayPal支付策略
        strategy = factory.getStrategy("paypal");
        strategy.pay(200);

        // 获取并使用比特币支付策略
        strategy = factory.getStrategy("bitcoin");
        strategy.pay(300);
    }
}

springboot自动注入特性

再次简化策略工厂类的初始化

//策略接口 和 实现类
public interface PaymentStrategy {
    void pay(int amount);
    String getType();
}

@Component
public class CreditCardPayment implements PaymentStrategy {}

@Component
public class PayPalPayment implements PaymentStrategy {}

@Component
public class BitcoinPayment implements PaymentStrategy {}

工厂类

  1. @PostConstruct 是 Java 中的一个注解,常用于 Spring 框架中。它标注的方法会在依赖注入完成之后自动执行。换句话说,当 Spring 完成了对 PaymentStrategyFactory 类中所有依赖的注入后,它会自动调用这个标注了 @PostConstruct 的方法

  2. 定义策略接口和具体策略实现类,并使用@Component注解标记。

    在工厂类中,通过构造器注入所有实现了策略接口的Bean。

    @PostConstruct方法中,将策略实现类放入Map中,以策略类型作为键,对应的策略实现类作为值。

@Component
public class PaymentStrategyFactory {

    private final List<PaymentStrategy> strategies;
    private Map<String, PaymentStrategy> strategyMap;

    //自动注入
    @Autowired
    public PaymentStrategyFactory(List<PaymentStrategy> strategies) {
        this.strategies = strategies;
    }

    //注入后自动执行
    @PostConstruct
    public void init() {
        strategyMap = new HashMap<>();
        for (PaymentStrategy strategy : strategies) {
            strategyMap.put(strategy.getType(), strategy);
        }
    }

    //根据策略得到相应的策略实现类
    public PaymentStrategy getStrategy(String type) {
        return strategyMap.get(type.toLowerCase());
    }
}

使用

PaymentStrategy strategy = factory.getStrategy("creditcard");
strategy.pay(100);

参考

  1. https://blog.csdn.net/lk142500/article/details/122372638
  2. https://refactoringguru.cn/design-patterns/strategy