观察者模式的简单概念
假设现在有A、B、C、D等四个独立的对象,其中B、C、D这三个对象想在A对象发生改变的第壹时间知道这种改变,以便做出相应的响应。
上面的这种情形,就是观察者模式。当然每個被观察者可以有多个观察者,每個观察者也可以有多个被观察者。观察者与被观察者也不是对立的,壹個对象可以观察其他对象,也可以被其他对象观察。
观察者模式的应用场景
为了更好的理解什么是观察者模式,下面列举壹些可能用到该模式的情形或例子:
(1)周期性任务。比如linux中的周期性任务命令crontab命令,win7 下的定时关机命令shutdown -s -t 1200(1200s后关机)。当预期系统时间到后,这些命令就可以通知相应的观察者激活相应的命令并执行对应操作。
(2)重新加载配置文件。现在做大型系统基本都会有配置文件,例如在SSH项目中每次修改配置文件后,都需要重新启动服务器才能使得新的配置文件生效,当然SSH中貌似已经提供了参数设置,当配置文件修改时,可以自动重新加载。
观察者模式相关的 Java 类
1
2
3
4
5
6
7
8
9
10
11
|
java.util.Observable
//继承该类的子类是可以被观察的,在观察者模式中充当被观察者
API 中的相关说明如下:This
class
represents an observable object, or
"data"
in the model-view paradigm. It can be subclassed to represent an object that the application wants to have observed.
An observable object can have one or more observers. An observer may be any object that
implements
interface
Observer. After an observable instance changes, an application calling the Observable's notifyObservers method causes all of its observers to be notified of the change by a call to their update method.
The order in which notifications will be delivered is unspecified. The
default
implementation provided in the Observable
class
will notify Observers in the order in which they registered interest, but subclasses may change
this
order, use no guaranteed order, deliver notifications on separate threads, or may guarantee that their subclass follows
this
order, as they choose.
Note that
this
notification mechanism is has nothing to
do
with threads and is completely separate from the wait and notify mechanism of
class
Object.
When an observable object is newly created, its set of observers is empty. Two observers are considered the same
if
and only
if
the equals method returns
true
for
them.
|
1
2
3
|
java.util.Observer
//实现该接口的类在观察者模式中可以充当观察者,实现该类的时候需要实现这个接口中的update()方法。
API 中的说明很简洁,就壹句话:A
class
can implement the Observer
interface
when it wants to be informed of changes in observable objects.
|
如何实现简单的观察者模式
接下来我们实现壹個简单的被观察者类 ExampleObservable ,代码如下:
1
2
3
4
5
6
7
8
9
10
11
|
import
java.util.Observable;
public
class
ExampleObservable
extends
Observable {
int
data =
0
;
public
void
setData(
int
data){
this
.data = data;
this
.setChanged();
//标记此 Observable对象为已改变的对象
this
.notifyObservers();
//通知所有的观察者
}
}
|
再实现壹個观察者类 ExampleObserver,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
import
java.util.Observable;
import
java.util.Observer;
public
class
ExampleObserver
implements
Observer {
//有被观察者发生变化,自动调用对应观察者的update方法
@Override
public
void
update(Observable object, Object argument) {
//通过强制类型转换获取被观察者对象
ExampleObservable example = (ExampleObservable)object;
System.out.println(
"example.data changed, the new value of data is "
+ example.data);
}
}
|
1
2
3
4
5
6
7
8
9
10
|
public
class
Main {
public
static
void
main(String[] args) {
ExampleObservable example =
new
ExampleObservable();
example.addObserver(
new
ExampleObserver());
//给example这个被观察者添加观察者,允许添加多個观察者
example.setData(
2
);
example.setData(-
5
);
example.setData(
9999
);
}
}
|
运行之后在控制台输出如下结果:
1
2
3
|
example.data changed, the
new
value of data is
2
example.data changed, the
new
value of data is -
5
example.data changed, the
new
value of data is
9999
|
通过输出结果我们可以了解到,当 ExampleObservable 类的实例 example 的成员变量 data 的值发生改变时,ExampleObserver 对象都能够监测到,然后调用 update() 方法打印壹句话到控制台,说明以上的结果是符合我们预期的。
既是观察者又是被观察者
对于壹個类而言,可以既是观察者又是被观察者,只要既继承 Observable 类,又实现 Observer 接口就可以了。接下来给出壹個类似的例子。例子中 ObserverA 和 ObserverB 既是观察者又是被观察者,它们互相监听着对方的改变。
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
|
//ObserverA.java
import
java.util.Observable;
import
java.util.Observer;
public
class
ObserverA
extends
Observable
implements
Observer {
@Override
public
void
update(Observable object, Object arg) {
ObserverB observerB = (ObserverB)object;
System.out.println(
"observerB changed, the new value of observerB.data is "
+ observerB.data);
this
.setChanged();
this
.notifyObservers();
}
}
//ObserverB.java
import
java.util.Observable;
import
java.util.Observer;
public
class
ObserverB
extends
Observable
implements
Observer {
int
data =
0
;
@Override
public
void
update(Observable object, Object arg) {
System.out.println(
"ObserverB found that ObserverA changed..."
);
}
public
void
setData(
int
data){
this
.data = data;
this
.setChanged();
this
.notifyObservers();
}
}
//Main.java
import
net.oschina.bairrfhoinn.multiply.ObserverA;
import
net.oschina.bairrfhoinn.multiply.ObserverB;
public
class
Main {
public
static
void
main(String[] args) {
ObserverA a =
new
ObserverA();
ObserverB b =
new
ObserverB();
a.addObserver(b);
b.addObserver(a);
b.setData(
2
);
}
}
|
1
2
|
observerB changed, the
new
value of observerB.data is
2
ObserverB found that ObserverA changed...
|
之所以会出现上述运行结果,最初 ObserverA 和 ObserverB 相互之间作为观察者与被观察者,但是 ObserverB 的实例 b 先调用的 setData() 方法,然后 ObserverA 的实例 a 观察到了这個变化,于是调用了本类的 update 方法打印出了第壹行,紧接着 ObserverA 的 update() 方法在方法体中声明了自己发生了变化,于是 ObserverB 观察了这個情况,也调用了自身的 update() 方法并打印了第二句话。