设计模式(17)-观察者模式

Observer
思想:定 义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所 有依赖于它的对象都得到通知并被自动更新。
场景:上面描述该模式思想的文字可能显得有些拗口,实际上你也不用想得过于复杂。只要你写过任何的基于图形界面的程序,那么实际上您对他是一 点也不该陌生的。它就是我们每一次鼠标键盘敲击都在我们的程序内部流转着的事件机制的基础。当一个事件发生,则通知订阅该事件的对象。
实现:上 面的UML图看似复杂,实际上,去理解它的最好的办法就是试着思考和使用任何一种OO语 言来定义一个拥有事件机制的类。比如,.Net下,你只要好好去看看关于delegate的 文档,尝试着根据MSDN写写看一个最简单的自定义事件。那么,上面的UML图, 我敢保证你能很轻易的看明白。
重构成本:高。

Observer观察者设计模式用于将对象的变化通知给感兴趣的用户。在Observer模式中的角色为主题(subject)与观察者(observer),观察者订阅它感兴趣的主题,一个主题可以被多个观 察者订阅,当主题的状态发生变化时,它必须通知(notify)所有订阅它的观察者,观察者检视主题的状态变化,并作出对应的动作,所以Observer模式也称之为Publish-Subscribe模式。 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
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
//主题
interface Subject{
//注册观察者
public void registerObserver(Observer o);
//注销观察者
public void unregisterObserver(Observer o);
//通知观察者
public void notifyObservers();
}
//观察者
interface Observer{
//更新价格信息
public void update(float price);
}
//商品
class Product implements Subject{
//观察者列表
private List<Observer> observers = new ArrayList<Observer>();
private float price;
public void registerObserver(Observer o){
observers.add(o);
}
public void unregisterObserver(Observer o){
observers.remove(o);
}
public void notifyObservers(){
for(Observer observer : observers){
//主题向观察者推送更新数据
observer.update(price);
}
}
public void priceChanged(){
notifyObservers();
}
public void setPrice(float price){
this.price = price;
priceChanged();
}
}
//订阅者
class Subscriber implements Observer{
private float currentPrice;
//观察者引用主题
private Subject product;
public Subscriber(Subject product){
this.product = product;
//主题注册观察者
product.registerObserver(this);
}
public void update(float price){
this. currentPrice = price;
System.out.println(“Current price change to:” + currentPrice);
}
}
public class ObserverDemo{
public static void main(String[] args){
Subject product = new Product();
Subscriber subscriber = new Subscriber(product);
product.setPrice(10.98);
product.setPrice(998.15);
}
}

在Java的java.util中内置了Observer观察者设计模式,其中:
(1).java.util.Observable是主题类,所有继承了该类的类是事件发生的主题,也是被观察的对象。java.util.Observable的常用方法有:
a.public void addObserver(Observer o):为主题添加观察者。
b.publicvoid deleteObserver(Observer o):删除某个观察者。
c.publicvoid deleteObservers():删除主题上的所有观察者。
d.publicboolean hasChanged():测试主题是否改变。
e.protectedvoid setChanged():标记该主题对象已经改变。
f.publicvoid notifyObservers():通知所有观察者对象已经已经改变。
(2).java.util.Observer接口是观察者,所有实现了该接口的类都是主题事件的观察者,该接口只有一个方法需要实现:
publicvoid update(Observable o, Object arg):通知观察者更新已经改变的主题。
使用JDK内置的Observer观察者设计模式,演示电子商务网站商品价格的例子如下:

1
2
3
4
5
6
7
8
9
10
11
在Java的java.util中内置了Observer观察者设计模式,其中:
(1).java.util.Observable是主题类,所有继承了该类的类是事件发生的主题,也是被观察的对象。java.util.Observable的常用方法有:
a.public void addObserver(Observer o):为主题添加观察者。
b.publicvoid deleteObserver(Observer o):删除某个观察者。
c.publicvoid deleteObservers():删除主题上的所有观察者。
d.publicboolean hasChanged():测试主题是否改变。
e.protectedvoid setChanged():标记该主题对象已经改变。
f.publicvoid notifyObservers():通知所有观察者对象已经已经改变。
(2).java.util.Observer接口是观察者,所有实现了该接口的类都是主题事件的观察者,该接口只有一个方法需要实现:
publicvoid update(Observable o, Object arg):通知观察者更新已经改变的主题。
使用JDK内置的Observer观察者设计模式,演示电子商务网站商品价格的例子如下:

Observer观察者设计模式在界面编程中应用广泛,一个button往往会注册一个onclickListener,里面有onclickAction方法对点击进行响应,此时button充当的就是主题,而onclickListener就是观察者,而onclickAction就对应着观察者中对事件进行响应的update方法。
JDK中观察者模式的应用:
•java.util.Observer
•java.util.Observable
•java.util.EventListener
•javax.servlet.http.HttpSessionBindingListener
•javax.servlet.http.HttpSessionAttributeListener
•javax.faces.event.PhaseListener