Observer观察者设计模式用于将对象的变化通知给感兴趣的用户。在Observer模式中的角色为主题(subject)与观察者(observer),观察者订阅它感兴趣的主题,一个主题可以被多个观察者订阅,当主题的状态发生变化时,它必须通知(ontify)所有订阅它的观察者,观察者检视主题的状态变化,并作出对应的动作,所以Observer模式也称之为Publish_Subscribe模式。Observer观察者设计模式结构如下:
观察者模式顺序图如下:
以一个电子商务网站商品价格变时通知订阅用户为例,演示Observer观察者设计模式,代码如下:
//主题
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.Observer是主题类,所有继承了该类的类是事件发生的主题,也是被观察的对象。java.util.Observable的常用方法有:
a.public void addObserver(Observer o):为主题添加观察者。
b.public void deleteObserver(Observer o):删除某个观察者。
c.public void deleteObservers():删除主题上的所有观察者。
d.public boolean hasChanged():测试主题是否改变。
e.protected void setChanged():标记该主题对象已经改变。
f.public void notifyObservers():通知所有观察者对象已经改变。
(2)java.util.Observer接口是观察者,所有实现了该接口的类都是主题事件的观察者,该接口只有一个方法需要实现:
public void update(Observer o,Object arg):通知观察者更新已经改变的主题。
使用JDK内置的Observer观察者设计模式,演示电子商务网站商品价格的例子如下:
//商品
class Product extends Observable{
private float price;
public void priceChanged(){
//设置变化点
setChanged();
//通知观察者
notifyObservers();
}
public void setPrice(float price){
this.price = price;
priceChanged();
}
public float getPrice(){
return price;
}
}
//订阅者
class Subscriber implements Observer{
private float currentPrice;
//观察者引用主题
private Observable observable;
public Subscriber(Observable observable){
this.observable = observable;
//主题注册观察者
observable.addObserver(this);
}
public void update(Observable observable,Object arg){
if(observable instanceof Product){
Product product = (Product)observable;
this.currentPrice = product.getPrice();
System.out.println("Current price change to:" + currentPrice);
}
}
}
public class ObserverDemo{
public static void main(String[] args){
Observable product = new Product();
Subscriber subscriber = new Subscriber(product);
product.setPrice(10.98);
product.setPrice(98.15);
}
}
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