Skip to content

观察者模式

基础概念

什么是观察者模式?

答案: 观察者模式(Observer Pattern)定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。

使用场景

  • 事件监听
  • 消息订阅
  • 数据变化通知

优点

  • 解耦,观察者和被观察者松耦合
  • 支持广播通信
  • 符合开闭原则

缺点

  • 观察者过多会影响性能
  • 可能造成循环依赖

实现方式

基本实现?

答案:

java
// 观察者接口
public interface Observer {
    void update(String message);
}

// 具体观察者
public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " 收到消息: " + message);
    }
}

// 被观察者(主题)
public class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

实际应用

事件监听

答案:

java
// 订单事件
public class OrderEvent {
    private Long orderId;
    private String eventType;

    public OrderEvent(Long orderId, String eventType) {
        this.orderId = orderId;
        this.eventType = eventType;
    }
}

// 监听器接口
public interface OrderListener {
    void onOrderCreated(OrderEvent event);
    void onOrderPaid(OrderEvent event);
}

// 库存监听器
public class StockListener implements OrderListener {
    @Override
    public void onOrderCreated(OrderEvent event) {
        System.out.println("库存服务:锁定库存");
    }

    @Override
    public void onOrderPaid(OrderEvent event) {
        System.out.println("库存服务:扣减库存");
    }
}

// 订单服务
public class OrderService {
    private List<OrderListener> listeners = new ArrayList<>();

    public void addListener(OrderListener listener) {
        listeners.add(listener);
    }

    public void createOrder(Long orderId) {
        System.out.println("创建订单: " + orderId);
        OrderEvent event = new OrderEvent(orderId, "CREATED");
        for (OrderListener listener : listeners) {
            listener.onOrderCreated(event);
        }
    }
}

Spring中的观察者模式

ApplicationListener?

答案:

java
// 自定义事件
public class UserRegisterEvent extends ApplicationEvent {
    private String username;

    public UserRegisterEvent(Object source, String username) {
        super(source);
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}

// 监听器
@Component
public class EmailListener implements ApplicationListener<UserRegisterEvent> {
    @Override
    public void onApplicationEvent(UserRegisterEvent event) {
        System.out.println("发送注册邮件给: " + event.getUsername());
    }
}

// 发布事件
@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher publisher;

    public void register(String username) {
        System.out.println("用户注册: " + username);
        publisher.publishEvent(new UserRegisterEvent(this, username));
    }
}

练习题

  1. 观察者模式和发布订阅模式的区别?
  2. 如何实现异步观察者?
  3. 观察者模式如何避免内存泄漏?
  4. Spring事件机制的原理?
  5. 如何实现观察者的优先级?

Released under the MIT License.