观察者模式

“订阅对方,就是注册自己。”

设计逻辑

观察者模式很适合用“读者订阅信息”来说明,而书上更是直言“出版者 + 订阅者 = 观察者模式”。现假设有这样一个新闻机构p,它会以when、where、what的形式向订阅它的读者c们发送信息。实现一种一对多的依赖,这样一来p一旦改变状态,它的所有订阅者都会收到通知并更新。

注册

注册的逻辑是发生在新闻机构内部的,只有通过注册,它才能知道去更新哪些订阅者的信息。首先抽象出P:

1
2
3
4
5
interface P {
public void registerC(C c);
public void removeC(C c);
public void notifyC();
}

接下来实现具体的“新闻机构”:

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
class ImlP implements P {
private ArrayList cs;
private String when;
private String where;
private String what;
public ImlP() {
cs = new ArrayList();
}
@Override
public void registerC(C c) {
cs.add(c);
}
@Override
public void removeC(C c) {
int i = cs.indexOf(c);
if (i >= 0) {
cs.remove(i);
}
}
@Override
public void notifyC() {
for (int i = 0; i < cs.size(); i++) {
C c = (C)cs.get(i);
c.update(when, where, what);
}
}
public void reSetData(String when, String where, String what) {
this.when = when;
this.where = where;
this.what = what;
notifyC();
}
}

代码中,注册是ImlP的方法,通过该方法,将订阅者某c注册在自己的内部容器中。

订阅

首先抽象出订阅者:

1
2
3
interface C {
public void update(String when, String where, String what);
}

接下来实现具体的订阅者:

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
class ImlC implements C, Message{
private String when;
private String where;
private String what;
private P p;
public ImlC(P p) {
this.p = p;
p.registerC(this);
}
@Override
public void update(String when, String where, String what) {
this.when = when;
this.where = where;
this.what = what;
message();
}
@Override
public void message() {
System.out.println("时间:" + when + "\n地点:" + where + "\n事件:" + what);
}
}

这里用到了一个辅助类Message:

1
2
3
interface Message {
void message();
}

测试用例

1
2
3
4
5
6
public static void main(String[] args) {
P specP = new ImlP();
C specC = new ImlC(specP);
((ImlP)specP).reSetData("早上十点", "叙利亚", "停战");
}

设计模式的原则

这个例子我学习到的设计原则:

  • 设计原则1:为了交互对象之间的松耦合设计而努力。