Administrator
Published on 2025-04-24 / 11 Visits
0
0

使用观察者模式(Observer)与传统方式对比优势

在 Spring Boot 中使用观察者模式的典型场景是解耦事件发布与事件处理逻辑。以下通过一个用户注册场景(注册后发送邮件、记录日志、赠送积分)对比观察者模式与传统方式的实现差异。


观察者模式实现代码

1. 定义事件类

// 事件类
public class UserRegisteredEvent extends ApplicationEvent {
    private String username;
    private String email;

    public UserRegisteredEvent(Object source, String username, String email) {
        super(source);
        this.username = username;
        this.email = email;
    }
    // Getters...
}

2. 定义监听器

// 发送邮件监听器
@Component
public class EmailListener {
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        System.out.println("Sending email to: " + event.getEmail());
    }
}

// 记录日志监听器
@Component
public class LogListener {
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent event) {
        System.out.println("Logging registration: " + event.getUsername());
    }
}

// 赠送积分监听器
@Component
public class PointsListener {
    @EventListener
    public void handleUserRegistered(UserRegisteredEvent) {
        System.out.println("Adding 100 points to user");
    }
}

3. 事件发布者(Service)

@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void registerUser(String username, String email) {
        // 1. 用户注册核心逻辑
        System.out.println("Registering user: " + username);

        // 2. 发布事件
        eventPublisher.publishEvent(new UserRegisteredEvent(this, username, email));
    }
}

传统方式实现代码(无观察者模式)

@Service
public class UserService {
    @Autowired
    private EmailService emailService;
    @Autowired
    private LogService logService;
    @Autowired
    private PointsService pointsService;

    public void registerUser(String username, String email) {
        // 1. 用户注册核心逻辑
        System.out.println("Registering user: " + username);

        // 2. 直接调用后续处理(高耦合)
        emailService.sendEmail(email);
        logService.logRegistration(username);
        pointsService.addPoints(username, 100);
    }
}


两种方式对比分析

1. 代码结构差异

​​维度​​

​​观察者模式​​

​​传统方式​​

​耦合性​

事件发布者与处理者完全解耦

强耦合,需直接依赖具体服务

​扩展性​

新增逻辑只需添加监听器,无需修改原有代码

需修改 UserService,违反开闭原则

​代码复用性​

事件处理逻辑可被多个事件复用

逻辑分散在多个调用点

​异步能力​

天然支持异步处理(加 @Async 注解即可)

需手动实现线程池或异步调用

2. 观察者模式优势

  1. ​解耦性​
    事件发布者不关心有多少个监听器,新增/删除逻辑无需修改核心业务代码。

  2. ​可扩展性​
    添加新功能(如注册后发送短信)只需新增监听器,无需触碰 UserService

  3. ​维护性​
    事件处理逻辑集中管理,避免核心业务代码臃肿。

  4. ​异步处理​
    通过 @Async 可轻松实现异步操作,提升系统吞吐量:

    @Async
    @EventListener
    public void handleUserRegisteredAsync(UserRegisteredEvent event) {
        // 异步处理逻辑
    }
  5. ​事件驱动架构基础​
    为后续集成消息队列(如 RabbitMQ、Kafka)提供平滑过渡。

适用场景

  • ​跨模块通信​​:如订单创建后通知库存、物流系统。

  • ​异步任务​​:如耗时操作(发送短信、生成报表)。

  • ​审计日志​​:记录关键操作日志。

  • ​业务状态变更​​:如用户权限变更后更新缓存。

观察者模式通过松耦合的设计,使得系统在面对需求变化时更具弹性和可维护性。


Comment