设计模式(15)——观察者模式
本文介绍观察者模式的概念和应用。
# 基本思想和原则
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。另外观察者模式又被称为发布/订阅模式。
# 动机
当一个对象的状态变化会导致其他对象的变化时,可以考虑使用观察者模式。
# 实现
public class Server extends Observable {
private String name;
public Server(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void cpuOverload() {
System.out.println(this.getName() + " CPU overload.");
super.setChanged();
super.notifyObservers("cpu overload");
}
public void diskOverload() {
System.out.println(this.getName() + " disk overload.");
super.setChanged();
super.notifyObservers("disk overload");
}
}
public class Monitor implements Observer {
private String name;
public Monitor(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void update(Observable o, Object arg) {
String msg = (String)arg;
Server server = (Server)o;
if (msg.equalsIgnoreCase("cpu overload")) {
System.out.println(this.getName() + " got cpu overload message of " + server.getName() + ".");
} else if (msg.equalsIgnoreCase("disk overload")) {
System.out.println(this.getName() + " got disk overload message of " + server.getName() + ".");
}
}
}
public class Test {
public static void main(String[] args) {
Server server1 = new Server("Server_1");
Monitor monitor1 = new Monitor("Monitor_1");
Monitor monitor2 = new Monitor("Monitor_2");
server1.addObserver(monitor1);
server1.addObserver(monitor2);
server1.cpuOverload();
server1.diskOverload();
}
}
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
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
输出如下:
Server_1 CPU overload.
Monitor_2 got cpu overload message of Server_1.
Monitor_1 got cpu overload message of Server_1.
Server_1 disk overload.
Monitor_2 got disk overload message of Server_1.
Monitor_1 got disk overload message of Server_1.
1
2
3
4
5
6
2
3
4
5
6
上面的代码模拟了一个监控器监视服务器状态的场景,这个场景中服务器是被观察者,监控器是观察者。注意Server
类继承了Observable
类,Observable
类中已经实现了addObserver
、deleteObserver
和notifyObservers
这几个方法,用于添加观察者,删除观察者和通知观察者,其在内部维护了一个观察者数组,通知观察者时遍历这个观察者数组,一个个通知即可。另外Server
类在cpuOverload
和diskOverload
两个方法中将 CPU 过载和磁盘过载的事件通知观察者。
Monitor
类实现了Observer
接口,这个接口只有一个方法需要实现:
void update(Observable o, Object arg);
1
update
方法是在被观察者通知观察者的时候被调用的,在这个方法中观察者会收到两个参数:被观察者对象的引用和一个通知数据参数,观察者在这个方法中对被观察者发生的状态变动做出自己的响应。
Java 中对观察者模式已经有了很好的封装,一般情况下我们只需将被观察者继承Observable
类,观察者实现Observer
接口,然后编写自己的业务逻辑即可,非常方便。
# 优点
观察者模式建立了一套抽象的事件触发机制,观察者和被观察之间可以独立扩展。
# 缺点
在使用观察者模式时要注意不要建立过长的观察链,这有可能导致性能问题,出问题时排查也较为困难。
编辑 (opens new window)
上次更新: 2024-07-15, 03:27:09