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

引言

作为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开发者工具箱中的重要组成部分。在实际项目中,我们应该根据业务场景灵活选择和应用这些模式,而不是生搬硬套。

相关推荐
evans在进步10 分钟前
Spring Boot 工程化核心详解:Parent、Starter、热部署、事务与多数据源
spring boot·后端·python
宫水三叶的刷题日记44 分钟前
馋猫外卖:AI 让字节式试错没有天花板
后端
SomeB1oody1 小时前
【RustyML入门】7.4. 按需裁剪与模块化集成
开发语言·后端·机器学习·rust·教程
罗超驿1 小时前
SpringBoot 快速入门
java·spring boot·后端
卷无止境2 小时前
除了开发api,FastAPI其实也可以配合jinja2模板写页面
后端·python·fastapi
newerp2 小时前
Redis 操作与缓存策略
后端·程序员·go
newerp2 小时前
GORM ORM 基础
后端·程序员·go
小岛前端2 小时前
AI Skills 已经封神,但新的问题却越来越严重!
前端·后端·github
拖孩2 小时前
一个人 + AI 做的小程序,上线 15 天赚了 10 块 5
前端·后端·微信小程序
newerp2 小时前
CRUD 操作与预处理语句
后端·程序员·go