使用策略+工厂模式实现不同支持方式

在 Spring Boot 中,我们可以利用 Spring 工厂模式(基于 @Component 注入策略)来管理策略类,避免 new 和 if-else,让代码符合 开闭原则(OCP)。

实现思路

1.定义策略接口:所有策略类实现此接口。
2.实现具体策略类:使用 @Component 让 Spring 自动管理策略类。
3.创建策略工厂:
    ① @Autowired 获取 Spring 容器中所有策略类(Map<String, PaymentStrategy>)。
    ② Map 的 key 是策略标识(@Component("标识")),value 是策略对象。
    ③ 通过 Map.get(type) 获取策略,避免 if-else。
4.在业务层调用策略工厂。
5.创建 Spring Boot Controller,提供 HTTP 接口。

1、定义策略接口

  • 所有支付策略类都要实现这个接口:
public interface PaymentStrategy {
    void pay(double amount);
}

2、定义具体策略类

  • 支付宝支付策略
import org.springframework.stereotype.Component;

@Component("ALIPAY")  // 以 "ALIPAY" 作为 key 存入 Spring 容器
public class AlipayPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("✅ 使用支付宝支付:" + amount + " 元");
    }
}
  • 微信支付策略
import org.springframework.stereotype.Component;

@Component("WECHAT") // 以 "WECHAT" 作为 key
public class WeChatPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("✅ 使用微信支付:" + amount + " 元");
    }
}
  • 信用卡支付策略
import org.springframework.stereotype.Component;

@Component("CREDIT_CARD") // 以 "CREDIT_CARD" 作为 key
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("✅ 使用信用卡支付:" + amount + " 元");
    }
}

3、设计策略工厂

  • 自动收集 Spring 容器中的策略
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;

@Component
public class StrategyFactory {
    private final Map<String, PaymentStrategy> strategyMap;

    @Autowired
    public StrategyFactory(Map<String, PaymentStrategy> strategyMap) {
        this.strategyMap = strategyMap;
    }

    public PaymentStrategy getStrategy(String type) {
        PaymentStrategy strategy = strategyMap.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("❌ 不支持的支付方式:" + type);
        }
        return strategy;
    }
}

📌 解释

  • Spring 自动收集所有 @Component 识别的策略类,存入 strategyMap。
  • @Component("ALIPAY") 这样的标识成为 Map 的 key,对应的策略对象成为 value。
  • getStrategy(type) 方法 根据 key 查找策略,避免 if-else。

4、业务层调用策略工厂

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PaymentService {
    private final StrategyFactory strategyFactory;

    @Autowired
    public PaymentService(StrategyFactory strategyFactory) {
        this.strategyFactory = strategyFactory;
    }

    public void pay(String type, double amount) {
        PaymentStrategy strategy = strategyFactory.getStrategy(type);
        strategy.pay(amount);
    }
}

📌 解释

  • PaymentService 作为业务层,调用 StrategyFactory.getStrategy(type) 获取策略对象。
  • 调用 strategy.pay(amount); 执行支付操作。

5、创建 Controller,提供 HTTP 接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/payment")
public class PaymentController {
    private final PaymentService paymentService;

    @Autowired
    public PaymentController(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    @GetMapping("/{type}/{amount}")
    public String pay(@PathVariable String type, @PathVariable double amount) {
        paymentService.pay(type, amount);
        return "支付成功";
    }
}

📌 解释

  • 访问 /payment/{type}/{amount},调用不同的支付策略。
  • type 对应 @Component("标识"),如 ALIPAY、WECHAT。
  • amount 代表支付金额。

6、Spring Boot 项目结构

spring-strategy-pattern
├── src/main/java/com/example
│   ├── strategy/
│   │   ├── PaymentStrategy.java        # 策略接口
│   │   ├── AlipayPayment.java          # 支付宝支付策略
│   │   ├── WeChatPayment.java          # 微信支付策略
│   │   ├── CreditCardPayment.java      # 信用卡支付策略
│   │   ├── StrategyFactory.java        # 策略工厂
│   ├── service/
│   │   ├── PaymentService.java         # 业务层调用策略
│   ├── controller/
│   │   ├── PaymentController.java      # Spring Boot 接口
│   ├── Application.java                # 启动类
└── pom.xml

7、pom.xml 依赖

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot DevTools(可选,开发时热加载) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
</dependencies>

8、测试:调用 API

GET http://localhost:8080/payment/ALIPAY/100

✅ 控制台输出

✅ 使用支付宝支付:100.0 元

🔥 总结

方式优点缺点
Spring 工厂模式自动管理策略,避免 new 和 if-else,扩展性强依赖 Spring 容器
传统 if-else简单直接违反开闭原则,不易扩展
反射方式避免 if-else,动态加载性能略低,代码复杂
枚举方式线程安全,适用于固定策略不能动态扩展

🚀 Spring 工厂模式是最推荐的实现方式!
💡 如果你的项目基于 Spring,优先采用 @Component 注入策略工厂,代码更优雅、更易维护! 🎯


从前书信很慢,车马很远,一生只够爱一个人


随缘惜缘不攀缘
1 声望0 粉丝

寒江孤影,江湖故人,相逢何必曾相识!