初学设计模式【2】观察者模式——Observer[续]

  在Observer观察者模式中介绍了观察者模式,这一篇中我们看一下Java对观察者模式内置的支持。在java.util包中有一个Observable类,还有一个Observer接口。

1.Observable类

  从字面意思来理解,这是一个“可被观察者”,对应于观察者模式中的"主题“接口。

源码:

View Code
  1 public class Observable {
  2     private boolean changed = false;
  3     private Vector obs;
  4    
  5     /** Construct an Observable with zero Observers. */
  6 
  7     public Observable() {
  8     obs = new Vector();
  9     }
 10 
 11     /**
 12      * Adds an observer to the set of observers for this object, provided 
 13      * that it is not the same as some observer already in the set. 
 14      * The order in which notifications will be delivered to multiple 
 15      * observers is not specified. See the class comment.
 16      *
 17      * @param   o   an observer to be added.
 18      * @throws NullPointerException   if the parameter o is null.
 19      */
 20     public synchronized void addObserver(Observer o) {
 21         if (o == null)
 22             throw new NullPointerException();
 23     if (!obs.contains(o)) {
 24         obs.addElement(o);
 25     }
 26     }
 27 
 28     /**
 29      * Deletes an observer from the set of observers of this object. 
 30      * Passing <CODE>null</CODE> to this method will have no effect.
 31      * @param   o   the observer to be deleted.
 32      */
 33     public synchronized void deleteObserver(Observer o) {
 34         obs.removeElement(o);
 35     }
 36 
 37     /**
 38      * If this object has changed, as indicated by the 
 39      * <code>hasChanged</code> method, then notify all of its observers 
 40      * and then call the <code>clearChanged</code> method to 
 41      * indicate that this object has no longer changed. 
 42      * <p>
 43      * Each observer has its <code>update</code> method called with two
 44      * arguments: this observable object and <code>null</code>. In other 
 45      * words, this method is equivalent to:
 46      * <blockquote><tt>
 47      * notifyObservers(null)</tt></blockquote>
 48      *
 49      * @see     java.util.Observable#clearChanged()
 50      * @see     java.util.Observable#hasChanged()
 51      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
 52      */
 53     public void notifyObservers() {
 54     notifyObservers(null);
 55     }
 56 
 57     /**
 58      * If this object has changed, as indicated by the 
 59      * <code>hasChanged</code> method, then notify all of its observers 
 60      * and then call the <code>clearChanged</code> method to indicate 
 61      * that this object has no longer changed. 
 62      * <p>
 63      * Each observer has its <code>update</code> method called with two
 64      * arguments: this observable object and the <code>arg</code> argument.
 65      *
 66      * @param   arg   any object.
 67      * @see     java.util.Observable#clearChanged()
 68      * @see     java.util.Observable#hasChanged()
 69      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
 70      */
 71     public void notifyObservers(Object arg) {
 72     /*
 73          * a temporary array buffer, used as a snapshot of the state of
 74          * current Observers.
 75          */
 76         Object[] arrLocal;
 77 
 78     synchronized (this) {
 79         /* We don't want the Observer doing callbacks into
 80          * arbitrary code while holding its own Monitor.
 81          * The code where we extract each Observable from 
 82          * the Vector and store the state of the Observer
 83          * needs synchronization, but notifying observers
 84          * does not (should not).  The worst result of any 
 85          * potential race-condition here is that:
 86          * 1) a newly-added Observer will miss a
 87          *   notification in progress
 88          * 2) a recently unregistered Observer will be
 89          *   wrongly notified when it doesn't care
 90          */
 91         if (!changed)
 92                 return;
 93             arrLocal = obs.toArray();
 94             clearChanged();
 95         }
 96 
 97         for (int i = arrLocal.length-1; i>=0; i--)
 98             ((Observer)arrLocal[i]).update(this, arg);
 99     }
100 
101     /**
102      * Clears the observer list so that this object no longer has any observers.
103      */
104     public synchronized void deleteObservers() {
105     obs.removeAllElements();
106     }
107 
108     /**
109      * Marks this <tt>Observable</tt> object as having been changed; the 
110      * <tt>hasChanged</tt> method will now return <tt>true</tt>.
111      */
112     protected synchronized void setChanged() {
113     changed = true;
114     }
115 
116     /**
117      * Indicates that this object has no longer changed, or that it has 
118      * already notified all of its observers of its most recent change, 
119      * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>. 
120      * This method is called automatically by the 
121      * <code>notifyObservers</code> methods. 
122      *
123      * @see     java.util.Observable#notifyObservers()
124      * @see     java.util.Observable#notifyObservers(java.lang.Object)
125      */
126     protected synchronized void clearChanged() {
127     changed = false;
128     }
129 
130     /**
131      * Tests if this object has changed. 
132      *
133      * @return  <code>true</code> if and only if the <code>setChanged</code> 
134      *          method has been called more recently than the 
135      *          <code>clearChanged</code> method on this object; 
136      *          <code>false</code> otherwise.
137      * @see     java.util.Observable#clearChanged()
138      * @see     java.util.Observable#setChanged()
139      */
140     public synchronized boolean hasChanged() {
141     return changed;
142     }
143 
144     /**
145      * Returns the number of observers of this <tt>Observable</tt> object.
146      *
147      * @return  the number of observers of this object.
148      */
149     public synchronized int countObservers() {
150     return obs.size();
151     }
152 }

说明:相比我们在Observer观察者模式中自己写的Subject接口,有几个地方需要注意一下:1)setChanged()方法,此方法用于标记状态已经改变的事实,如果调用notifyObservers()方法前没有调用此方法,观察者就不会被通知,具体请看其源码。2)notifyObservers(Object arg)我们能过arg参数封装我们要推送给观察者s的数据。

2.Observer接口

  这个就是观察者们应该实现的”观察者接口“,里面只有一个update方法。

源码:

 1 public interface Observer {
 2     /**
 3      * This method is called whenever the observed object is changed. An
 4      * application calls an <tt>Observable</tt> object's
 5      * <code>notifyObservers</code> method to have all the object's
 6      * observers notified of the change.
 7      *
 8      * @param   o     the observable object.
 9      * @param   arg   an argument passed to the <code>notifyObservers</code>
10      *                 method.
11      */
12     void update(Observable o, Object arg);
13 }

 说明:update(Observable o, Object arg);o用来让观察者知道是哪个主题通知它,arg就是推送过来的数据。

  

 

 

posted @ 2013-04-26 15:50  g.hui  阅读(187)  评论(0)    收藏  举报