什么是监听者模式?简单地说,观察者模式定义了一个一对多的依赖关系,让一个或多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新。
在Java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。
Observer接口
这个接口只定义了一个方法,update()。当被观察者对象的状态发生变化时,这个方法就会被调用。这个方法的实现应当调用每一个被观察者对象的notifyObservers()方法,从而通知所有的观察对象。
Observable类
被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一个方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。
下面我们举个列子看看,这个模式怎么用代码实现。
1.Observer代码如下
public interface Observer {
/**
* 当被观察的对象发生变化时,这个方法会被调用。
*/
void update(Observable o, Object arg);
}
2.Observable代码如下
public class Observable {
private boolean changed = false;
private Vector obs;
/**
* 用0个观察者构造一个被观察者。
*
* @return
**/
public Observable() {
obs = new Vector();
}
/**
* 将一个观察者加到观察者列表上面。
*/
public synchronized void addObserver(Observer o) {
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 将一个观察者对象从观察者列表上删除。
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
/**
* 相当于 notifyObservers(null)
*/
public void notifyObservers() {
notifyObservers(null);
}
/**
* 如果本对象有变化(那时hasChanged 方法会返回true) 调用本方法通知所有登记在案的观察者,即调用它们的update()方法,
* 传入this和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();
}
/**
* 将“已变化”设为true
*/
protected synchronized void setChanged() {
changed = true;
}
/**
* 将“已变化”重置为false
*/
protected synchronized void clearChanged() {
changed = false;
}
/**
* 探测本对象是否已变化
*/
public synchronized boolean hasChanged() {
return changed;
}
/**
* 返还被观察对象(即此对象)的观察者总数。
*/
public synchronized int countObservers() {
return obs.size();
}
}
3.具体被观察者的实现public class ConcreteObservable extends Observable{
public void sendMessageToAll(){
setChanged();
notifyObservers(new Message(data.xiaohei));
}
}
4.具体观察者的实现,我这边举个A和B的例子
public class AObserver implements Observer{
public AObserver(){
}
@Override
public void update(Observable o, Object arg) {
Message result=(Message)arg;
if(result!=null&&result.tag==Message.data.xiaohei){
System.out.println("AObserver这个类正在处理");
}
}
}
public class BObserver implements Observer {
public BObserver() {
}
@Override
public void update(Observable o, Object arg) {
Message result = (Message) arg;
if (result != null && result.tag == Message.data.xiaowang) {
System.out.println("BObserver这个类正在处理");
}
}
}
5.定义具体被观察者中传递的消息对象public class Message {
public data tag;
public Message(data tag) {
this.tag = tag;
}
public static enum data {
xiaowang, xiaohei
}
}
6.测试如下
public class Test {
public static void main(String args[]) {
ConcreteObservable co = new ConcreteObservable();
Observer a = new AObserver();
Observer b = new BObserver();
co.addObserver(a);
co.addObserver(b);
co.sendMessageToAll();
}
}
7.输出结果如下
AObserver这个类正在处理