在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这个类正在处理