深入实战工厂模式与观察者模式:工厂模式与观察者模式在电商系统中的应用

引言

作为Java高级开发者,我经常需要在Spring Boot项目中应用设计模式来解决复杂的业务问题。今天我将分享工厂模式和观察者模式在电商系统中的实际应用,这些模式比常见的责任链和策略模式更有趣且实用。

1. 工厂模式在支付系统中的应用

在电商系统中,我们经常需要对接多种支付渠道(支付宝、微信支付、银联等),工厂模式非常适合这种场景。

业务场景

我们需要根据用户选择的支付方式创建不同的支付处理器,每种支付方式有不同的验证、处理和通知逻辑。

代码实现

首先定义支付接口:

java 复制代码
public interface PaymentService {
    PaymentResponse pay(PaymentRequest request);
    boolean supports(PaymentType type);
}

然后实现具体的支付服务:

java 复制代码
@Service
@RequiredArgsConstructor
public class AlipayService implements PaymentService {
    private final AlipayConfig config;
    
    @Override
    public PaymentResponse pay(PaymentRequest request) {
        // 支付宝特定的支付逻辑
        return new PaymentResponse("ALIPAY_SUCCESS", "支付宝支付成功");
    }
    
    @Override
    public boolean supports(PaymentType type) {
        return PaymentType.ALIPAY == type;
    }
}

@Service
@RequiredArgsConstructor
public class WechatPayService implements PaymentService {
    private final WechatConfig config;
    
    @Override
    public PaymentResponse pay(PaymentRequest request) {
        // 微信支付特定的支付逻辑
        return new PaymentResponse("WECHAT_SUCCESS", "微信支付成功");
    }
    
    @Override
    public boolean supports(PaymentType type) {
        return PaymentType.WECHAT == type;
    }
}

创建支付工厂:

java 复制代码
@Service
@RequiredArgsConstructor
public class PaymentServiceFactory {
    private final List<PaymentService> paymentServices;
    
    public PaymentService getPaymentService(PaymentType type) {
        return paymentServices.stream()
                .filter(service -> service.supports(type))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("不支持的支付类型"));
    }
}

在控制器中使用:

java 复制代码
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/payment")
public class PaymentController {
    private final PaymentServiceFactory paymentServiceFactory;
    
    @PostMapping
    public PaymentResponse pay(@RequestBody PaymentRequest request) {
        PaymentService paymentService = paymentServiceFactory.getPaymentService(request.getType());
        return paymentService.pay(request);
    }
}

优势分析

  1. 新增支付方式只需添加新的PaymentService实现,无需修改现有代码
  2. 支付逻辑与创建逻辑分离,符合单一职责原则
  3. Spring自动收集所有PaymentService实现,工厂类简洁高效

2. 观察者模式在订单状态变更中的应用

电商系统中,订单状态变更时需要触发多种操作(发送通知、更新库存、记录日志等),观察者模式非常适合这种一对多的依赖关系。

业务场景

当订单状态发生变化时,需要:

  1. 发送短信/邮件通知用户
  2. 更新库存(如果是取消订单)
  3. 记录操作日志
  4. 触发可能的促销活动结算

代码实现

定义订单事件:

java 复制代码
public class OrderEvent {
    private final Order order;
    private final OrderStatus oldStatus;
    private final OrderStatus newStatus;
    private final LocalDateTime eventTime;
    
    // 构造器、getter省略
}

定义事件发布者:

java 复制代码
@Service
@RequiredArgsConstructor
public class OrderEventPublisher {
    private final ApplicationEventPublisher eventPublisher;
    
    public void publishOrderStatusChange(Order order, OrderStatus oldStatus, OrderStatus newStatus) {
        OrderEvent event = new OrderEvent(order, oldStatus, newStatus, LocalDateTime.now());
        eventPublisher.publishEvent(event);
    }
}

实现观察者(使用Spring的事件机制):

java 复制代码
@Component
@RequiredArgsConstructor
public class OrderNotificationListener {
    private final NotificationService notificationService;
    
    @EventListener
    @Async
    public void handleOrderEvent(OrderEvent event) {
        if (event.getNewStatus() == OrderStatus.PAID) {
            notificationService.sendPaymentSuccessNotification(event.getOrder());
        } else if (event.getNewStatus() == OrderStatus.SHIPPED) {
            notificationService.sendShippingNotification(event.getOrder());
        }
        // 其他状态处理...
    }
}

@Component
@RequiredArgsConstructor
public class InventoryUpdateListener {
    private final InventoryService inventoryService;
    
    @EventListener
    @Async
    public void handleOrderCancellation(OrderEvent event) {
        if (event.getNewStatus() == OrderStatus.CANCELLED && 
            event.getOldStatus() == OrderStatus.PAID) {
            // 恢复库存
            inventoryService.restoreInventory(event.getOrder().getItems());
        }
    }
}

@Component
@RequiredArgsConstructor
public class OrderLogListener {
    private final OrderLogService logService;
    
    @EventListener
    public void logOrderStatusChange(OrderEvent event) {
        logService.logStatusChange(
            event.getOrder().getId(),
            event.getOldStatus(),
            event.getNewStatus(),
            event.getEventTime()
        );
    }
}

在订单服务中使用:

java 复制代码
@Service
@RequiredArgsConstructor
@Transactional
public class OrderService {
    private final OrderRepository orderRepository;
    private final OrderEventPublisher eventPublisher;
    
    public void updateOrderStatus(Long orderId, OrderStatus newStatus) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new OrderNotFoundException(orderId));
        
        OrderStatus oldStatus = order.getStatus();
        order.setStatus(newStatus);
        orderRepository.save(order);
        
        // 发布状态变更事件
        eventPublisher.publishOrderStatusChange(order, oldStatus, newStatus);
    }
}

优势分析

  1. 订单服务不需要知道有哪些组件关心状态变更,解耦明显
  2. 新增观察者只需添加新的监听器,不影响现有逻辑
  3. 使用Spring的@Async可以实现异步处理,提高响应速度
  4. 各观察者之间互不影响,可以独立演进

总结

工厂模式和观察者模式在Spring Boot项目中有着广泛的应用场景:

  1. ​工厂模式​特别适合需要根据不同条件创建不同实现类的场景,如支付系统、文件解析器等
  2. ​观察者模式​非常适合事件驱动的场景,如订单状态变更、用户注册等需要触发多种后续操作的业务

这两种模式都能显著提高代码的可维护性和扩展性,是Spring Boot开发者工具箱中的重要组成部分。在实际项目中,我们应该根据业务场景灵活选择和应用这些模式,而不是生搬硬套。

相关推荐
Flobby52916 分钟前
Go语言新手村:轻松理解变量、常量和枚举用法
开发语言·后端·golang
Warren981 小时前
Java Stream流的使用
java·开发语言·windows·spring boot·后端·python·硬件工程
程序视点2 小时前
IObit Uninstaller Pro专业卸载,免激活版本,卸载清理注册表,彻底告别软件残留
前端·windows·后端
xidianhuihui2 小时前
go install报错: should be v0 or v1, not v2问题解决
开发语言·后端·golang
进击的铁甲小宝4 小时前
Django-environ 入门教程
后端·python·django·django-environ
掘金码甲哥4 小时前
Go动态感知资源变更的技术实践,你指定用过!
后端
困鲲鲲4 小时前
设计模式:中介者模式 Mediator
设计模式·中介者模式
王柏龙5 小时前
ASP.NET Core MVC中taghelper的ModelExpression详解
后端·asp.net·mvc
无限大65 小时前
算法精讲:二分查找(二)—— 变形技巧
后端
勇哥java实战分享5 小时前
基于 RuoYi-Vue-Pro 定制了一个后台管理系统 , 开源出来!
后端