微信公众号

设计模式之观察者模式

观察者模式

观察者模式(Observer pattern),定义了对象间一种一对多的依赖关系,当 被观察者 状态发生变化,它的 观察者 们会收到通知并自动更新。

应用

在 Java 语言的 java.util 库里面,提供了一个 Observable 类以及一个 Observer 接口,构成 Java 语言对观察者模式的支持。

Android 观察者最常见有 addTextChangedListener 等。

Observable/Observer 示例

Observable 被观察者

被观察者,一个被观察者对象可以有数个观察者对象。

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
public class ConcreteObservable extends Observable {
private int data = 0;
public int getData() {
return data;
}
public void setData(int i) {
//具体逻辑按需
if (data != i) {
this.data = i;
setChanged();
}
}
private static ConcreteObservable observable;
public static synchronized ConcreteObservable getInstance() {
if (observable == null) {
observable = new ConcreteObservable();
}
return observable;
}
public ConcreteObservable post() {
//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
notifyObservers();
return observable;
}
public ConcreteObservable post(Object arg) {
setChanged();
//只有在setChange()被调用后,notifyObservers()才会去调用update(),否则什么都不干。
notifyObservers(arg);
return observable;
}
}

Observable 源码:

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public class Observable {
private boolean changed = false;
private final ArrayList<Observer> observers;
/** Construct an Observable with zero Observers. */
public Observable() {
observers = new ArrayList<>();
}
/**
* 将一个观察者添加到观察者集合
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!observers.contains(o)) {
observers.add(o);
}
}
/**
* 删除观察者
*/
public synchronized void deleteObserver(Observer o) {
observers.remove(o);
}
/**
* 如果该对象发生了变化,由所指示的 hasChanged方法,则通知其所有观察者,并调用clearChanged方法来指示该对象不再改变
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* 如果该对象发生了变化,由所指示的 hasChanged方法,则通知其所有观察者,并调用clearChanged方法来指示该对象不再改变
*/
public void notifyObservers(Object arg) {
Observer[] arrLocal;
synchronized (this) {
if (!hasChanged())
return;
arrLocal = observers.toArray(new Observer[observers.size()]);
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
arrLocal[i].update(this, arg);
}
/**
* 清除观察者列表,不再有任何观察者
*/
public synchronized void deleteObservers() {
observers.clear();
}
/**
* 观测对象为已改变
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* 指示对象不再改变,或者说,它已通知其所有最近改变其观察员
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* 测试此对象已经改变
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* 返回观察者人数
*/
public synchronized int countObservers() {
return observers.size();
}
}

Observer 观察者

Observer 是个接口,在需要观察的地方实现:

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
public class ObserverActivity extends AppCompatActivity implements Observer {
ConcreteObservable observable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_observer);
observable = ConcreteObservable.getInstance();
observable.addObserver(this);
observable.setData(1);
observable.post();
observable.setData(1);
observable.post();
observable.post(2);
}
@Override
public void update(Observable o, Object arg) {
ConcreteObservable concreteObservable = (ConcreteObservable) o;
Log.d("wxl", "ObserverActivity=" + concreteObservable.getData() + ",arg=" + arg);
}
@Override
protected void onDestroy() {
super.onDestroy();
//删除观察者
observable.deleteObserver(this);
}
}

Observer源码:

1
2
3
4
5
6
public interface Observer {
/**
* 当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会* 调用这一方法。
*/
void update(Observable o, Object arg);
}

最后打印:

1
2
ObserverActivity=1,arg=null
ObserverActivity=1,arg=2



联系我

1、我的微信公众号:吴小龙同学,欢迎关注交流~
2、我的微信群,可以加我微信,拉你进群,加我时请备注真名
3、我的小密圈:更多分享只对你公开,¥99/永久。
由于多说和网易云跟帖评论服务相继关闭,本博客决定不再折腾评论,大家可以前往我的公众号留言交流,抱歉了!