观察者模式

什么是观察者模式

观察者模式又叫做发布订阅模式,类似于微信公众号,一个发布端,多个接收端。
观察者模式定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
通俗的讲,就是在被观察类中,持有一个观察类的集合,然后在数据改变的时候,遍历所有观察类,调用更新方法。

实现观察者模式

建立观察者模式的步骤

  1. 编写观察者接口和被观察者的接口
  2. 实现观察者和被观察者
  3. 注册观察者
  4. 通知观察者

编写观察者接口和被观察者的接口

java中已经准备了这两个接口,观察者接口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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public interface Observer {//观察者的接口
void update(Observable observable, Object data);//只有一个用于更新的方法
}
public class Observable {//被观察者类
List<Observer> observers = new ArrayList<Observer>();//内部持有一个观察者的List集合
boolean changed = false;//数据是否改变的标志位
public Observable() {}

public void addObserver(Observer observer) {//添加观察者
if (observer == null) {//防止空指针异常
throw new NullPointerException("observer == null");
}
synchronized (this) {//同步锁
if (!observers.contains(observer))//判断是否已经添加观察者
observers.add(observer);//如果没有就添加
}
}
protected void clearChanged() {//清空数据是否改变的标志位
changed = false;
}
public int countObservers() {//返回观察者的数量
return observers.size();
}
public synchronized void deleteObserver(Observer observer) {//移除某个观察者
observers.remove(observer);
}
public synchronized void deleteObservers() {//移除所有观察者
observers.clear();
}
public boolean hasChanged() {//获取数据是否改变的标志位
return changed;
}
public void notifyObservers() {//拉模式更新数据
notifyObservers(null);
}
@SuppressWarnings("unchecked")
public void notifyObservers(Object data) {//推模式更新数据,推送data
int size = 0;
Observer[] arrays = null;//临时存放当前观察者的状态,参见备忘录模式
synchronized (this) {
if (hasChanged()) {//数据是否发生改变
clearChanged();//清空标志位
size = observers.size();
arrays = new Observer[size];
observers.toArray(arrays);
}
}
if (arrays != null) {
for (Observer observer : arrays) {
observer.update(this, data);
}
}
}
protected void setChanged() {//设置数据发生改变
changed = true;
}
}

实现观察者和被观察者

1
2
3
4
5
6
7
8
9
10
11
12
public class Observer1 implements Observer{//观察者
public void update(Observable observable, Object data) {
Log.i("Observer1", "change");
}
}
public class Subject extends Observable{//被观察者
public void change(){
setChanged();//必须调用这个方法确认修改数据
notifyObservers();通知所有观察者
}

}

注册观察者

1
2
3
Subject s = new Subject();//new一个被观察者
Observer1 o1 = new Observer1();//new一个观察者
s.addObserver(o1);//进行注册

通知观察者

1
s.change();  //调用被观察者的