对象件有一对多的关系。当一个对象被修改时,要自动通知依赖它的对象
为了弱化对象之间的依赖
事例
需求:芒果没库存了,爱吃芒果的客户想要在芒果到货时收到短信通知
数据结构如图:
抽象类及其代码如下:
观察者
public abstract class Observer {
public abstract void update();
}
public class CustomerObserver extends Observer {
@Override
public void update() {
// 客户收到通知,去购买芒果
}
}
被观察者。持有一个观察者列表,并对外提供通知观察者的方法
public abstract class Attention {
private List<Observer> mObservers = new ArrayList<>();
// 通知所有观察者,执行观察者的update()
public void notifyObservers() {
for (Observer observer : mObservers) {
observer.update();
}
}
// 添加观察者
public void addObserver(Observer observer) {
mObservers.add(observer);
}
// 移除观察者
public void removeObserver(Observer observer) {
mObservers.remove(observer);
}
}
public class MangoAttention extends Attention {
public void perform() {
// ...到货的其他业务
// 通知观察者
notifyObservers();
}
}
java.util包给我们也提供了现成的Observer接口和Observable类
事例代码如下
public class CustomerObserver implements Observer {
// 参数一是发通知的Observable,参数二是通知带过来的数据
@Override
public void update(Observable o, Object arg) {
// 客户收到通知,去购买芒果
}
}
public class MangoAttention extends Observable {
public void perform() {
// ...到货的其他业务
// 通知观察者。java.util的需要先setChanged()标记为已修改,再notifyObservers()
setChanged();
notifyObservers(null);
}
}
总结
适用场景
- 一个对象发生变化时,需要通知其他对象
- 需要一个触发链。类似RxJava,A影响B、B影响C
优点
- 降低耦合
- 建立了一套触发机制
缺点
- 观察者太多时,通知方法会耗时,需要转为异步
- 观察者和被观察者有依赖时,可能死循环