观察者模式
基础概念
什么是观察者模式?
答案: 观察者模式(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));
}
}练习题
- 观察者模式和发布订阅模式的区别?
- 如何实现异步观察者?
- 观察者模式如何避免内存泄漏?
- Spring事件机制的原理?
- 如何实现观察者的优先级?