1. 设计模式之观察者模式:监听目标对象的状态改变
1.1. 介绍
观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间一对多的依赖关系,使得当一个对象(被观察者/主题)状态改变时,所有依赖它的对象(观察者)都会自动收到通知并更新。
常见场景
例如,前端开发中,部分组件,点击按钮等,会添加监听,当点击后会出发函数方法调用。
例如,zookeeper 在分布式系统之间协调调用:
- (1)系统 A 尝试在 zk 上一把锁,获取到并成功加锁
- (2)系统 B 也尝试在 zk 上一把锁,加锁失败,在 zk 上加一个监听器(观察者)
- (3)系统 A 将锁释放后,zk 感受到锁被释放,会立即通知系统 B 注册的监听器
- (4)系统 B 收到监听通知,再尝试加锁
1.2. 优缺点及建议
优点
- 解耦主题和观察者,易于扩展。
- 支持动态注册和注销观察者。
- 符合开闭原则(OCP)。
缺点
- 观察者过多时通知耗时(需优化)。
- 观察者需实现统一接口(可能不灵活)。
- 循环依赖可能导致无限通知。
使用建议
- 小规模场景:手动实现观察者模式。
- 大规模系统:使用消息中间件(如RabbitMQ)实现发布-订阅。
- 考虑使用Java内置的观察者模式支持类,如java.util.Observable和java.util.Observer。
注意事项
- 避免循环引用:注意观察者和主题之间的依赖关系,避免循环引用。
- 异步执行:考虑使用异步通知避免单点故障导致整个系统卡壳。
1.3. 实现及相关代码
接口及数据对象
import java.util.Observable;
import java.util.Observer;
public static class Subject extends Observable {
private Integer state;
public Subject(Integer state) {
this.state = state;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
// 在这里状态就改变了
this.state = state;
// 通知关联的一些观察者,状态变化了
this.setChanged();
// this.notifyObservers(state);
this.notifyObservers();
}
}
public static class ConcreteObserver implements Observer {
public void update(Observable o, Object arg) {
// Integer state = (Integer) arg;
Subject subject = (Subject) o;
Integer state = subject.getState();
System.out.println("目标对象的状态变化成:" + state);
}
}
调用方法
public static void main(String[] args) {
Subject subject = new Subject(0);
Observer observer = new ConcreteObserver();
subject.addObserver(observer);
subject.setState(1);
subject.setState(2);
}