观察者模式 (Observer Pattern)
定义对象间的一对多依赖,当一个对象改变时,所有依赖者自动收到通知
目录
概述
观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
模式结构
适用场景
- 事件处理系统
- 发布-订阅模型
- 数据变更通知
- 消息队列
基础实现
手动实现
// 观察者接口
public interface Observer {
void update(String event, Object data);
}
// 被观察者接口
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers(String event, Object data);
}
// 具体被观察者
public class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String event, Object data) {
for (Observer observer : observers) {
observer.update(event, data);
}
}
// 业务方法
public void publishNews(String news) {
System.out.println("发布新闻: " + news);
notifyObservers("NEWS_PUBLISHED", news);
}
}
// 具体观察者:邮件通知
public class EmailSubscriber implements Observer {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
@Override
public void update(String event, Object data) {
if ("NEWS_PUBLISHED".equals(event)) {
System.out.println("发送邮件到 " + email + ": 新新闻 " + data);
}
}
}
// 具体观察者:短信通知
public class SmsSubscriber implements Observer {
private String phone;
public SmsSubscriber(String phone) {
this.phone = phone;
}
@Override
public void update(String event, Object data) {
if ("NEWS_PUBLISHED".equals(event)) {
System.out.println("发送短信到 " + phone + ": 新新闻");
}
}
}
// 使用
NewsPublisher publisher = new NewsPublisher();
publisher.attach(new EmailSubscriber("user@example.com"));
publisher.attach(new SmsSubscriber("13800138000"));
publisher.publishNews("Java 21 发布了!");Java 内置实现
import java.util.Observable;
import java.util.Observer;
// 被观察者(Java 9 后已废弃,建议使用 Flow API)
public class WeatherData extends Observable {
private float temperature;
public void setTemperature(float temperature) {
this.temperature = temperature;
setChanged(); // 标记状态已改变
notifyObservers(temperature); // 通知观察者
}
}
// 观察者
public class WeatherDisplay implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("温度更新: " + arg);
}
}
// 使用
WeatherData weatherData = new WeatherData();
weatherData.addObserver(new WeatherDisplay());
weatherData.setTemperature(25.5f);Spring Event
// 定义事件
public class OrderCreatedEvent extends ApplicationEvent {
private final Order order;
public OrderCreatedEvent(Object source, Order order) {
super(source);
this.order = order;
}
public Order getOrder() {
return order;
}
}
// 发布事件
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createOrder(Order order) {
orderRepository.save(order);
eventPublisher.publishEvent(new OrderCreatedEvent(this, order));
}
}
// 监听事件:发送邮件
@Component
public class OrderEmailListener {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
Order order = event.getOrder();
System.out.println("发送订单确认邮件: " + order.getId());
}
}
// 监听事件:更新库存
@Component
public class OrderInventoryListener {
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
Order order = event.getOrder();
System.out.println("扣减库存: " + order.getProductId());
}
}优缺点
| 优点 | 缺点 |
|---|---|
| 松耦合 | 通知顺序不确定 |
| 支持广播通信 | 可能循环依赖 |
| 易于扩展 | 内存泄漏风险 |
总结
观察者模式是实现事件驱动架构的基础。Spring Event 提供了企业级的实现,支持同步/异步、事务等多种特性。