使用策略+工厂模式实现不同支持方式
在 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 注入策略工厂,代码更优雅、更易维护! 🎯
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。