1 概述
观察者模式(observer Pattern),也叫发布-订阅模式,是一种很重要的行为模式,它被广泛运用在异步编程之中,可以说是异步编程的基础。
2 观察者模式
当我们需要关注某个对象的状态时,可以不断地轮询,查看状态是否变化,这也就是我们熟知的同步方式。然而这样的方式效率很低,在对象状态真正变化之前,任何的检查都是对服务器资源的浪费。更好的方法是,当对象状态改变的时候,可以有一种通知机制,告诉别人状态发生了变化。观察者模式,正是实现这种机制的关键。
观察者模式中,观察者可以注册到自己感兴趣的被观察对象上,当被观察对象的状态发生变化,或某个事件放生时,逐个调用观察者的方法来通知它们。这种异步的方式,很大程度上提高了运行效率
现实生活中,观察者模式也很常见。比如网购了一件商品,我们不用时不时地去收货点查看快递有没有到,而是当收到“商品已送达”的短信的时候,直接去取就行。此例中,当我们购买商品的时候,相当于关注了快递的状态,当状态变为“已送达”的时候,我们会得到通知。
3 案例
举一个代码案例。当我们关注了某个公众号之后,便可以收到公众号的文章推送,这其实就是典型的观察者模式的例子:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
public interface Observable<T> {
void addSubscriber(Observer observer);
void removeSubscriber(Observer observer);
void publish(T object);
}
public class PublicAccount implements Observable<Article> {
private String name;
private Collection<Observer> subscribers;
private Collection<Article> articles;
PublicAccount(String name) {
this.name = name;
subscribers = new ArrayList<>();
articles = new LinkedList<>();
};
@Override
public synchronized void addSubscriber(Observer observer) {
subscribers.add(observer);
}
@Override
public synchronized void removeSubscriber(Observer observer) {
subscribers.remove(observer);
}
@Override
public synchronized void publish(Article article) {
articles.add(article);
System.out.println(name + " is publishing new article...");
for (Observer subscriber : subscribers) {
subscriber.update(article);
}
}
}
public interface Observer<T> {
void update(T object);
}
public class ArticleFans implements Observer<Article> {
private String name;
ArticleFans(String name) {
this.name = name;
};
@Override
public void update(Article article) {
System.out.println(name + " got article「" + article.getName() + "」");
}
}
public class Article {
private String name;
private String content;
Article(String name, String content) {
this.name = name;
this. content = content;
};
public String getName() {
return name;
}
}
public class Test {
public static void main(String[] args) {
PublicAccount publicAccount = new PublicAccount("Jump x Switch");
ArticleFans link = new ArticleFans("Link");
ArticleFans mario = new ArticleFans("Mario");
publicAccount.addSubscriber(link);
publicAccount.addSubscriber(mario);
Article article = new Article("Pro Controller is on discount!", "……");
publicAccount.publish(article);
}
}
输出:
1
2
3
Jump x Switch is publishing new article...
Link got article「Pro Controller is on discount!」
Mario got article「Pro Controller is on discount!」
我们关注了公众号,其实就是把自己加入了公众号的观察者列表,当公众号发布新文章的时候,所有关注它的人,都会得到文章的推送。
JDK
中的java.util.Observable和java.util.Observer,是观察者模式的简单实现,不过现实中使用不多(在SWT
中应用很多)。
观察者模式更多见于事件通知模型的框架中,如Netty
中随处可见ChannelFuture和GenericFutureListener的组合;也可见于Redis
的Pub/Sub,ZooKeeper
的Watches……
4 总结
观察者模式允许我们在对象状态改变时得到通知,在一些高性能框架中得到了广泛的应用,是异步编程的基础。