springboot策略设计模式最佳实践
假设我们希望实现以下需求:
- 支付方式(如支付宝、微信支付)可以动态切换。
- 支付方式配置从配置文件中加载,或者支持在数据库中动态更新。
- 配置文件或数据库中指定当前生效的支付方式。
步骤 1: 配置文件定义支付方式
我们可以在 application.yml
或 application.properties
中定义支付方式配置项,指定默认的支付方式。
# application.yml payment: defaultMethod: alipay
这里我们定义了一个 payment.defaultMethod
配置项,它用于指定当前选择的支付方式。假设我们有多个支付方式,默认支付方式是 alipay
。
步骤 2: 在 PaymentContext
中加载动态配置
为了根据配置动态选择支付方式,我们需要将配置文件中的 defaultMethod
读入,并根据它来确定使用哪个支付策略。可以通过 Spring 的 @Value
注解来注入配置项。
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.Map; @Service public class PaymentContext { private final Map<String, PaymentStrategy> paymentStrategies; @Value("${payment.defaultMethod}") private String defaultPaymentMethod; public PaymentContext(Map<String, PaymentStrategy> paymentStrategies) { this.paymentStrategies = paymentStrategies; } public void executePayment(double amount) { // 根据配置的支付方式动态选择策略 PaymentStrategy strategy = paymentStrategies.get(defaultPaymentMethod); if (strategy != null) { strategy.pay(amount); } else { throw new IllegalArgumentException("Invalid payment method: " + defaultPaymentMethod); } } }
在这个 PaymentContext
中,我们通过 @Value
注解将 application.yml
中的 payment.defaultMethod
配置项注入到 defaultPaymentMethod
变量中。然后在 executePayment
方法中,根据配置项选择对应的支付策略执行支付。
步骤 3: 动态更新支付方式(可选)
如果您希望在运行时动态切换支付方式,可以考虑将支付方式配置存储在数据库中。通过查询数据库中的配置项,可以灵活地更新支付方式。
假设我们有一个 PaymentConfig
表,包含 method_code
和 enabled
等字段来表示当前生效的支付方式。
@Entity public class PaymentConfig { @Id private Long id; private String methodCode; private Boolean enabled; // getters and setters }
接着,可以通过 Spring Data JPA 访问数据库中的配置:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class DynamicPaymentConfigService { private final PaymentConfigRepository paymentConfigRepository; @Autowired public DynamicPaymentConfigService(PaymentConfigRepository paymentConfigRepository) { this.paymentConfigRepository = paymentConfigRepository; } public String getActivePaymentMethod() { List<PaymentConfig> activeConfigs = paymentConfigRepository.findByEnabled(true); // 假设返回第一个启用的支付方式 if (!activeConfigs.isEmpty()) { return activeConfigs.get(0).getMethodCode(); } return null; // 如果没有配置,返回空 } }
然后在 PaymentContext
中使用这个动态配置服务来更新支付方式:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Map; @Service public class PaymentContext { private final Map<String, PaymentStrategy> paymentStrategies; private final DynamicPaymentConfigService dynamicPaymentConfigService; @Autowired public PaymentContext(Map<String, PaymentStrategy> paymentStrategies, DynamicPaymentConfigService dynamicPaymentConfigService) { this.paymentStrategies = paymentStrategies; this.dynamicPaymentConfigService = dynamicPaymentConfigService; } public void executePayment(double amount) { // 从数据库或配置中获取当前启用的支付方式 String activePaymentMethod = dynamicPaymentConfigService.getActivePaymentMethod(); if (activePaymentMethod != null) { PaymentStrategy strategy = paymentStrategies.get(activePaymentMethod); if (strategy != null) { strategy.pay(amount); } else { throw new IllegalArgumentException("Invalid payment method: " + activePaymentMethod); } } else { throw new IllegalStateException("No active payment method configured."); } } }
通过上述方式,我们可以从数据库动态获取当前启用的支付方式,并在执行支付时应用它。
步骤 4: 控制器调用(不暴露支付方式)
在控制器层面,我们依然只关心执行支付,而不会暴露具体的支付方式。支付方式的选择完全依赖于配置文件或数据库中的设置。
import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/payment") public class PaymentController { private final PaymentContext paymentContext; @Autowired public PaymentController(PaymentContext paymentContext) { this.paymentContext = paymentContext; } @PostMapping("/pay") public String pay(@RequestParam double amount) { try { paymentContext.executePayment(amount); return "支付成功!"; } catch (IllegalArgumentException | IllegalStateException e) { return e.getMessage(); } } }
总结
- 动态配置:通过
application.yml
或数据库存储支付方式配置,能够动态切换支付方式而不暴露给前端请求 URL。 - 灵活扩展:新增支付方式时,只需要实现一个新的支付策略类,并在配置文件或数据库中添加相应的配置,无需修改控制器或核心业务逻辑。
- 安全性:通过不暴露支付方式具体实现,只提供支付功能接口,增加了安全性和封装性。
这种设计不仅能够支持多种支付方式,还能够根据配置灵活切换支付策略,适应不同的支付场景。
本文作者:唐钰逍遥
本文链接:https://www.cnblogs.com/tyxy/p/18534129
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步