参考:http://wwangcg.iteye.com/blog/1309952
观察者模式是对象的行为模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
Java的设计模式很多,观察者模式被称为是模式中的皇后,而且Java jdk也对它做了实现,可见该设计模式的重要位置。情形类似于评审们评审唱歌者,唱歌者唱歌的同时,通知评审者进行打分一系列操作。在图形化设计的软件中,为了实现视图和事件处理的分离,大多都采用了Observer模式,比如Java的Swing,Flex的ActionScript等。在现实的应用系统中也有好多应用,比如像当当网、京东商城一类的电子商务网站,如果你对某件商品比较关注,可以放到收藏架,那么当该商品降价时,系统给您发送手机短信或邮件。这就是观察者模式的一个典型应用,商品是被观察者,有的叫主体;关注该商品的客户就是观察者。下面的一个事例将模拟这个应用。
在java的util包中实现了该设计模式的框架,大部分应用都可以直接用它,当然了你也可以自己实现它,实际上就是一个被观察者的抽象类和一个观察者接口。被观察者的抽象类java.util.Observable。
package java.util;
/**
* 被观察者
*/
public class Observable {
private boolean changed = false; //是否状态发生变化
private Vector obs; //当状态发生变化时,需要通知的观察者对象集合
//构造函数,默认初始化观察者对象集
public Observable() {
obs = new Vector();
}
/**
* 添加观察者对象
* @param o 观察者对象
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 删除一个指定的观察者
* @param o 观察者对象
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
/**
* 通知观察者们
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* 通知所有的观察者
* @param arg 传递的消息
*/
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);
}
/**
* 删除所有的观察者
*/
public synchronized void deleteObservers() {
obs.removeAllElements();
}
/**
* 设置状态变更
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* 清除变更
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* 是否有变更
* @return
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* 返回观察者数量
* @return
*/
public synchronized int countObservers() {
return obs.size();
}
}
观察者的接口java.util.Observer
package java.util;
import java.util.Observable;
/**
* 观察者对象
*/
public interface Observer {
/**
* 根据被观察者的状态变更对应的处理方法
* @param o 被观察者对象
* @param arg 被观察者传递过来的参数
*/
void update(Observable o, Object arg);
}
模式的应用举例:
package com.liangbinny.observable;
import java.util.Observable;
/**
* Observable 被观察者
*/
public class Subject extends Observable {
/**
* 业务处理方法
*/
public void doSomething() {
if (true) {
super.setChanged(); // 设置有变更
}
notifyObservers("我开始做事了..."); // 通知观察者做出处理
}
}
package com.liangbinny.observer;
import java.util.Observable;
import java.util.Observer;
/**
* 观察者一
* 被观察者通知观察者做事
*/
public class ObserverOne implements Observer{
/**
* 被观察者有操作时,通知观察者做出处理方法
* @param o 被观察者
* @param arg 被观察者处理业务操作传递给观察者的消息
*/
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者一对应做出处理,被观察者传递过来的消息为:"+arg);
}
}
package com.liangbinny.observer;
import java.util.Observable;
import java.util.Observer;
/**
* 观察者二
* 被观察者通知观察者做事
*/
public class ObserverTwo implements Observer{
/**
* 被观察者有操作时,通知观察者做出处理方法
* @param o 被观察者
* @param arg 被观察者处理业务操作传递给观察者的消息
*/
@Override
public void update(Observable o, Object arg) {
System.out.println("观察者二对应做出处理,被观察者传递过来的消息为:"+arg);
}
}
测试Main方法:
package com.liangbinny;
import com.liangbinny.observable.Subject;
import com.liangbinny.observer.ObserverOne;
import com.liangbinny.observer.ObserverTwo;
public class TestObserverModel {
public static void main(String[] args) {
//创建被观察者
Subject subject = new Subject();
//创建观察者
ObserverOne observerOne = new ObserverOne();
ObserverTwo observerTwo = new ObserverTwo();
//把两个观察者加到被观察者列表中
subject.addObserver(observerOne);
subject.addObserver(observerTwo);
//观察者执行业务操作
subject.doSomething();
}
}
打印结果:
观察者二对应做出处理,被观察者传递过来的消息为:我开始做事了...
观察者一对应做出处理,被观察者传递过来的消息为:我开始做事了...