北京北大青鸟学校讲解:Java语言提供的对观察者模式的支持

北京北大青鸟学校学术部老师介绍:在Java语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。

Observer接口

这个接口只定义了一个方法,update()。当被观察者对象的状态发生变化时,这个方法就会被调用。这个方法的实现应当调用每一个被观察者对象的notifyObservers()方法,从而通知所有的观察对象。(北大青鸟课程

北大青鸟学校

java.util提供的Observer接口的类图


package java.util;

public interface Observer
{
/**
* 当被观察的对象发生变化时,这个方法会被调用。
*/
void update(Observable o, Object arg);
}
代码清单5、java.util.Observer接口的源代码。

Observable类

北京北大青鸟学校讲师介绍,被观察者类都是java.util.Observable类的子类。java.util.Observable提供公开的方法支持观察者对象,这些方法中有两个对Observable的子类非常重要:一个是setChanged(),另一个是notifyObservers()。第一个方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。

北京北大青鸟学校讲师介绍,java.util.Observable类还有其它的一些重要的方法。比如,观察者对象可以调用java.util.Observable类的addObserver()方法,将对象一个一个加入到一个列表上。当有变化时,这个列表可以告诉notifyObservers()方法那些观察者对象需要通知。由于这个列表是私有的,因此java.util.Observable的子对象并不知道观察者对象一直在观察着它们。

北大青鸟学校

Java语言提供的被观察者的类图

被观察者类Observable的源代码:
 
 package java.util;
 public class Observable
  {
 private boolean changed = false;
 private Vector obs;
 
  /** 用0个观察者构造一个被观察者。**/
 
 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();
 }
 }
 

代码清单6、java.util.Observer接口的源代码。 (北大青鸟课程)

北京北大青鸟学校讲师介绍,这个Observable类代表一个被观察者对象。一个被观察者对象可以有数个观察者对象,一个观察者可以是一个实现Observer接口的对象。在被观察者对象发生变化时,它会调用Observable的notifyObservers方法,此方法调用所有的具体观察者的update()方法,从而使所有的观察者都被通知更新自己。见下面的类图:
北大青鸟学校

使用Java语言提供的对观察者模式的支持

发通知的次序在这里没有指明。Observerable类所提供的缺省实现会按照Observers对象被登记的次序通知它们,但是Observerable类的子类可以改掉这一次序。子类并可以在单独的线程里通知观察者对象;或者在一个公用的线程里按照次序执行。

北京北大青鸟学校讲解,当一个可观察者对象刚刚创立时,它的观察者集合是空的。两个观察者对象在它们的equals()方法返回true时,被认为是两个相等的对象。 (北京北大青鸟学校学术部提供)

 

北大青鸟网上报名
北大青鸟招生简章