观察者模式是一种行为型模式。
观察者模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,其他所有依赖的对象都会得到通知,并自动更新。
观察者模式又称为「发布-订阅模式」Publish-Subscribe
,是一种通知机制,让发送通知的一方(被观察者)和接收通知的一方(观察者)彼此分离,互不影响。
常见的场景:
- 🔖 比如 Github 的 Actions,其实就是观察者模式的一种体现,当我们根据规则进行了一些 git 操作后,Github Actions 会根据配置做一些操作,比如编译/检查格式等。
🎈 实现方式
- 🎗️ 「订阅者」实现统一的接口,发布者仅通过该接口与订阅者交互
- 通常会有对各订阅者跟踪一个发布者的事件,实现统一接口防止耦合
- 在接口中声明通知方法及其参数
⚠ 注意事项:
- 顺序执行通知时,可能会因为某一观察者导致卡壳,通常会采用异步的方式执行任务。
🛠️ 实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| public class Store {
private Map<String, Product> products = new HashMap<>();
// 希望订阅新上架的商品的人
private List<ProudctObserver> observers = new ArrayList<>();
public boolean addObserver(ProudctObserver pb) {
this.observers.add(pb);
}
pubilc boolean removeObserver(ProductObserver pb) {
return this.observers.remove(pb);
}
// 发布新商品
public void addNewProduct(String name, BigDecimal price) {
Product p = new Product(name, price);
products.put(name, p);
// 📧 通知观察者
observers.forEach(o -> o.onPublished(p));
}
// 更新商品价格
public void setProductPrice(String name, double price) {
Product p = products.get(name);
p.setPrice(price);
// 📧 通知观察者
observers.forEach(o -> o.onPriceChanged(p));
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // 被观察者实现统一的接口
interface ProductObserver {
void onPublished(Product product);
void onPriceChanged(Product product);
}
// 观察者对象
class Customer implements ProdcutObserver {
// ...
}
class Admin implements ProductObserver {
// ...
}
|
1
2
3
4
5
6
7
| // observer 观察者
Admin admin = new Admin();
Customer customer = new Customer();
// 注册观察者
store.addObserver(admin);
store.addObserver(customer);
|