当前位置: 首页 > news >正文

策略模式与工厂模式实战

策略模式与工厂模式实战引言策略模式和工厂模式是最常用的行为型和创建型设计模式在Spring应用中有广泛的应用场景。策略模式允许在运行时选择不同的算法或行为工厂模式则封装对象的创建过程。本文将详细介绍这两种模式在Spring中的实战应用包括支付策略、折扣计算、消息发送等典型场景。一、策略模式基础1.1 策略接口定义public interface PaymentStrategy { PayResult pay(Order order); RefundResult refund(Order order); default boolean supports(PaymentChannel channel) { return true; } } public enum PaymentChannel { ALIPAY, WECHAT_PAY, UNION_PAY, CREDIT_CARD } Data public class Order { private Long id; private BigDecimal amount; private PaymentChannel channel; // ... }1.2 策略实现Component public class AlipayStrategy implements PaymentStrategy { Override public PayResult pay(Order order) { // 调用支付宝SDK AlipayTradeService service new AlipayTradeService(); AlipayTradePayResponse response service.pay(order); return PayResult.builder() .success(response.isSuccess()) .transactionId(response.getTradeNo()) .amount(order.getAmount()) .build(); } Override public RefundResult refund(Order order) { // 支付宝退款逻辑 return null; } Override public boolean supports(PaymentChannel channel) { return channel PaymentChannel.ALIPAY; } } Component public class WechatPayStrategy implements PaymentStrategy { Override public PayResult pay(Order order) { // 调用微信支付SDK return PayResult.builder() .success(true) .transactionId(wx UUID.randomUUID()) .amount(order.getAmount()) .build(); } Override public RefundResult refund(Order order) { // 微信退款逻辑 return null; } Override public boolean supports(PaymentChannel channel) { return channel PaymentChannel.WECHAT_PAY; } }1.3 策略工厂Service public class PaymentStrategyFactory { private final MapPaymentChannel, PaymentStrategy strategies; public PaymentStrategyFactory( ListPaymentStrategy strategyList) { this.strategies strategyList.stream() .collect(Collectors.toMap( this::detectChannel, Function.identity() )); } private PaymentChannel detectChannel(PaymentStrategy strategy) { if (strategy instanceof AlipayStrategy) { return PaymentChannel.ALIPAY; } else if (strategy instanceof WechatPayStrategy) { return PaymentChannel.WECHAT_PAY; } throw new IllegalArgumentException(Unknown strategy); } public PaymentStrategy getStrategy(PaymentChannel channel) { PaymentStrategy strategy strategies.get(channel); if (strategy null) { throw new UnsupportedOperationException( Unsupported payment channel: channel); } return strategy; } }1.4 策略使用Service public class OrderService { private final PaymentStrategyFactory strategyFactory; public OrderService(PaymentStrategyFactory strategyFactory) { this.strategyFactory strategyFactory; } Transactional public PayResult processPayment(Order order) { PaymentStrategy strategy strategyFactory.getStrategy(order.getChannel()); return strategy.pay(order); } }二、折扣计算策略2.1 策略接口public interface DiscountStrategy { BigDecimal calculateDiscount(Order order); int getPriority(); boolean supports(Order order); } Data Builder public class DiscountResult { private BigDecimal originalAmount; private BigDecimal discountAmount; private BigDecimal finalAmount; private String discountType; }2.2 多种折扣策略Component Order(1) public class VipDiscountStrategy implements DiscountStrategy { Override public BigDecimal calculateDiscount(Order order) { if (!supports(order)) { return BigDecimal.ZERO; } // VIP会员享9折 return order.getAmount().multiply(new BigDecimal(0.1)); } Override public int getPriority() { return 1; } Override public boolean supports(Order order) { return VIP.equals(order.getCustomerType()); } } Component Order(2) public class SeasonalDiscountStrategy implements DiscountStrategy { Autowired private DiscountConfig config; Override public BigDecimal calculateDiscount(Order order) { if (!supports(order)) { return BigDecimal.ZERO; } BigDecimal discountRate new BigDecimal( config.getSeasonalDiscountRate()); return order.getAmount().multiply(discountRate); } Override public int getPriority() { return 2; } Override public boolean supports(Order order) { return config.isSeasonalPromotion(); } } Component Order(3) public class CouponDiscountStrategy implements DiscountStrategy { Override public BigDecimal calculateDiscount(Order order) { if (order.getCouponCode() null) { return BigDecimal.ZERO; } Coupon coupon couponService.findByCode(order.getCouponCode()); if (coupon null || !coupon.isValid(order)) { return BigDecimal.ZERO; } return coupon.calculateDiscount(order.getAmount()); } Override public int getPriority() { return 3; } Override public boolean supports(Order order) { return order.getCouponCode() ! null; } }2.3 策略组合Service public class DiscountService { private final ListDiscountStrategy strategies; public DiscountService(ListDiscountStrategy strategies) { // 按优先级排序 this.strategies strategies.stream() .sorted(Comparator.comparingInt(DiscountStrategy::getPriority)) .collect(Collectors.toList()); } public DiscountResult calculateTotalDiscount(Order order) { BigDecimal totalDiscount BigDecimal.ZERO; ListString appliedDiscounts new ArrayList(); BigDecimal remainingAmount order.getAmount(); for (DiscountStrategy strategy : strategies) { if (strategy.supports(order)) { BigDecimal discount strategy.calculateDiscount(order); // 限制折扣不超过剩余金额 discount discount.min(remainingAmount); totalDiscount totalDiscount.add(discount); remainingAmount remainingAmount.subtract(discount); appliedDiscounts.add(strategy.getClass().getSimpleName()); } } return DiscountResult.builder() .originalAmount(order.getAmount()) .discountAmount(totalDiscount) .finalAmount(order.getAmount().subtract(totalDiscount)) .appliedDiscounts(appliedDiscounts) .build(); } }三、工厂模式3.1 简单工厂Service public class MessageSenderFactory { public MessageSender createSender(MessageType type) { switch (type) { case EMAIL: return new EmailSender(); case SMS: return new SmsSender(); case PUSH: return new PushSender(); default: throw new IllegalArgumentException(Unknown type: type); } } }3.2 工厂方法public interface SenderFactory { MessageSender createSender(); } Component public class EmailSenderFactory implements SenderFactory { Override public MessageSender createSender() { return new EmailSender(); } } Component public class SmsSenderFactory implements SenderFactory { Override public MessageSender createSender() { return new SmsSender(); } }3.3 抽象工厂public interface NotificationFactory { MessageSender createMessageSender(); TemplateEngine createTemplateEngine(); NotificationChannel createChannel(); } Component public class EmailNotificationFactory implements NotificationFactory { Override public MessageSender createMessageSender() { return new SmtpSender(); } Override public TemplateEngine createTemplateEngine() { return new FreemarkerEngine(); } Override public NotificationChannel createChannel() { return new EmailChannel(); } }四、策略工厂组合4.1 动态选择Service public class IntegratedPaymentService { private final MapPaymentChannel, PaymentStrategy strategyMap; private final PaymentFactory factory; public IntegratedPaymentService( ListPaymentStrategy strategies, PaymentFactory factory) { this.strategyMap strategies.stream() .collect(Collectors.toMap( PaymentStrategyFactory::detectChannel, Function.identity() )); this.factory factory; } public PaymentResult pay(Order order) { // 根据配置选择策略 PaymentChannel channel order.getChannel(); // 优先使用配置的策略 PaymentStrategy strategy strategyMap.get(channel); // 获取支付网关 PaymentGateway gateway factory.createGateway(channel); // 执行支付 return strategy.pay(order, gateway); } }4.2 策略注册表Service public class StrategyRegistryT { private final MapString, T registry new ConcurrentHashMap(); private final ListStrategyDecoratorT decorators new ArrayList(); public void register(String key, T strategy) { registry.put(key, strategy); } public void registerDecorator(StrategyDecoratorT decorator) { decorators.add(decorator); } public T getStrategy(String key) { T strategy registry.get(key); if (strategy null) { throw new StrategyNotFoundException(key); } // 应用装饰器 for (StrategyDecoratorT decorator : decorators) { strategy decorator.decorate(key, strategy); } return strategy; } }五、实战案例5.1 订单类型处理public interface OrderProcessor { Order process(Order order); } Component public class StandardOrderProcessor implements OrderProcessor { Override public Order process(Order order) { // 标准订单处理逻辑 return order; } } Component public class WholesaleOrderProcessor implements OrderProcessor { Override public Order process(Order order) { // 批发订单特殊处理 validateWholesale(order); applyWholesaleDiscount(order); return order; } } Service public class OrderProcessingService { private final StrategyRegistryOrderProcessor registry; public OrderProcessingService( MapString, OrderProcessor processors) { this.registry new StrategyRegistry(); processors.forEach(registry::register); } public Order processOrder(Order order) { String type order.getType(); OrderProcessor processor registry.getStrategy(type); return processor.process(order); } }5.2 验证策略public interface ValidationStrategyT { ValidationResult validate(T target); } Component public class UserValidationStrategy implements ValidationStrategyUser { Override public ValidationResult validate(User user) { ValidationResult result new ValidationResult(); if (user.getUsername() null || user.getUsername().isEmpty()) { result.addError(username, 用户名不能为空); } if (user.getEmail() ! null !user.getEmail().contains()) { result.addError(email, 邮箱格式不正确); } return result; } } Service public class ValidationService { private final MapClass?, ValidationStrategy? strategies; public ValidationService( MapString, ValidationStrategy? strategyMap) { this.strategies strategyMap.entrySet().stream() .collect(Collectors.toMap( e - e.getKey(), Map.Entry::getValue )); } public T ValidationResult validate(T target) { SuppressWarnings(unchecked) ValidationStrategyT strategy (ValidationStrategyT) strategies.get(target.getClass()); if (strategy null) { return ValidationResult.success(); } return strategy.validate(target); } }六、最佳实践6.1 策略选择使用Primary标注默认策略使用Order或Priority控制执行顺序考虑策略组合而非单一选择。6.2 工厂使用使用Spring的Bean注册工厂方法考虑使用Builder模式简化复杂对象创建保持工厂简单避免业务逻辑。6.3 性能考虑使用缓存策略实例避免在策略中创建大对象考虑策略的懒加载。总结策略模式和工厂模式是解决不同情况使用不同实现问题的利器。通过Spring的依赖注入这些模式的实现更加简洁和可测试。在实际应用中应该根据具体场景选择合适的模式组合遵循开闭原则使系统具有良好的扩展性。
http://www.gsyq.cn/news/1327998.html

相关文章:

  • 大理足金回收银手镯回收PT990铂金回收钻石戒指回收旧首饰回收本地排名正规门店专业推荐哪家靠谱二手哪家强 - 检测回收中心
  • 无王无帝定乾坤,来自田间第一人:海棠悟道定尘寰
  • 3分钟终极指南:如何免费解锁QQ音乐加密格式,实现跨平台音乐自由
  • 终极虚拟显示器解决方案:如何用Parsec VDD完美解决远程游戏串流与无显示器主机难题
  • Linux HID驱动实战:为iMX6ULL开发板适配非标USB游戏手柄的完整避坑指南
  • 不止于安装:在Jetson Orin Nano上玩转IMX219,从驱动配置到AI推理实战
  • 浙江宁波工作服定制厂家怎么避坑?选劳保服定制厂家认准这几点 - 奔跑123
  • 避坑指南:bayesplot可视化时,你的MCMC诊断图可能‘骗’了你(R/Stan实战)
  • 地平线6地图有哪些 地平线6可以在手机上玩吗
  • UE5实战:手把手教你用AIController和PathFollowingComponent实现NPC智能移动(含源码解析)
  • 3分钟搞定OFD转PDF:免费开源工具Ofd2Pdf完整使用指南
  • GPU太贵跑不起?这6个优化技巧让LLM推理成本直降
  • AUTOSAR CP开篇 - 从零认识汽车软件革命
  • 暗黑3终极宏工具D3KeyHelper:5分钟配置你的自动战斗系统
  • 局部点状离散定位与全域连续空间感知技术解析UWB:局部点状离散定位|镜像:全域连续空间感知
  • 不到千元玩转空间AI?OpenCV OAK-D-Lite上手体验与避坑指南
  • 2026佛山市本地人必选的瓷砖空鼓专业维修公司TOP5推荐!卫生间空鼓翘边,厨房空鼓翘边,客厅空鼓翘边,全天响应,免费上门,5月专业瓷砖空鼓修复公司持证上岗师傅排名最新深度调研方案) - 一修哥修缮
  • 极域电子教室破解指南:3分钟重获电脑自主权,学习效率翻倍
  • 测试自动化标准化理念
  • 告别CentOS后,我为什么选择华为openEuler 23.03作为我的主力Linux服务器?
  • 告别Keil!用Clion+STM32CubeMX搭建C++开发环境(附LED闪烁实战)
  • 分期乐购物额度变现最全指南,详细教程一看就会! - 团团收购物卡回收
  • InnoSwitch3-Pro芯片解析:数字接口如何革新65W快充设计
  • CentOS 7.9 VNC配置避坑实录:从‘Connection refused’到成功连上的完整排错指南
  • 5分钟打造专属AI歌手:Retrieval-based-Voice-Conversion-WebUI语音克隆完整指南
  • 哈工大NLP期末考后复盘:从HMM到Transformer,这些知识点你掌握了吗?
  • 别再死记硬背公式了!用Python和PyTorch手把手拆解Diffusion Model的前向加噪与反向去噪
  • N_m3u8DL-RE:现代流媒体下载架构深度解析与技术实践
  • 五金冲压件厂家技术甄别:从工艺到交付的硬核参考 - 奔跑123
  • 别再为CV毕设选题发愁了!学长手把手教你用YOLOv8搞定一个能跑起来的项目(附完整代码)