设计模式-观察者模式

设计模式-观察者模式

观察者模式(Obersver)

  • 观察者模式是使用频率非常高的模式了,它定义了对象间一种一对多的关系,使得每当一个对象改变状态,则所有依赖它的对象都会收到通知,并且自动更新。
  • 例如:Java中的监听器Listener用的就是观察者模式。

UML类图:

mark

  • Subject: 具有注册和移除观察者,并且通知观察者的功能,主体是通过某种数据结构(可能是列表)来维护一张观察者列表实现这些操作的。
  • 观察者(Observer)的注册功能需要调用主体的registerObserver()方法。

实现:

  • 开发技术周报,每周会更新一些内容,但是不知道具体的更新时间,又想第一时间阅读更新内容。
  • 难道要一直按住F5等它更新么?那估计F5烂了可能都没有更新。其实我们只需要简单的订阅一下就好,当有新的内容更新的时候,会发邮件到你订阅的邮箱中。

上述例子中:

  • 订阅者就是观察者,技术周报就是被观察者

代码实现:

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
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

// 观察者:程序员
public class Coder implements Observer {

private final String name;

public Coder(String name) {
this.name = name;
}


public void update(Observable o, Object arg) {
System.out.println("收到的更新内容为" + o);
}

}


// 被观察者:主体(开发周报)
class Weekly extends Observable {

// 一对多的通知
private ArrayList<Observer> observers = new ArrayList<Observer>();

// 增加一个观察者
public void subscribe(Observer observer) {
observers.add(observer);
}

// 删除一个观察者
public void unsubscribe(Observer observer) {
observers.remove(observer);
}

@Override
public void notifyObservers(Object obj) {
observers.forEach(observer -> observer.update("数据更新了"));
}
}

JDK中自带的观察者模式的类

mark

  • java.util 包中内置了Observerobservable类,同时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
public class Observable {
private boolean changed = false;
private Vector<java.util.Observer> obs;

public Observable() {
obs = new Vector<>();
}

// 注册
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}

// 反注册
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}

// 反注册所有观察者
public synchronized void deleteObservers() {
obs.removeAllElements();
}

// 通知更新
public void notifyObservers() {
notifyObservers(null);
}

// 通知更新
public void notifyObservers(Object arg) {
Object[] arrLocal;

synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}

for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}

protected synchronized void setChanged() {
changed = true;
}

protected synchronized void clearChanged() {
changed = false;
}

public synchronized boolean hasChanged() {
return changed;
}

public synchronized int countObservers() {
return obs.size();
}
}
  • Observer接口则是比较简单的代码update()的参数中除了可以传递数据意外,还提供了被观察者的引用对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 */
public interface Observer {
/**
* This method is called whenever the observed object is changed. An
* application calls an <tt>Observable</tt> object's
* <code>notifyObservers</code> method to have all the object's
* observers notified of the change.
*
* @param o the observable object.
* @param arg an argument passed to the <code>notifyObservers</code>
* method.
*/
void update(Observable o, Object arg);
}

JDK中的实现:

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信