初学设计模式【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就是推送过来的数据。


浙公网安备 33010602011771号