觀察者顧名思義,就是一個觀察者,如當我們訂閱報紙,我們就是報紙的觀察者,報紙就是一個主題(Subject),我們可以訂閱報紙可以退訂報紙,而報社的一方只要有訂閱者就得時時刻刻地準備發送報紙.
看了HeadFirst沒事就拿Java Api裏面的源碼來參考下:
在java.util下有個Observable類,我們發現他有如下的操作和屬性:
其中changed表示我們要監視的對象是否發生了改變(對於報紙就是指:是否有新聞報紙需要發送)
obs是一個向量:
public Observable() {
obs = new Vector();
}
而addObserver(Observer )


1 public synchronized void addObserver(Observer o) { 2 if (o == null) 3 throw new NullPointerException(); 4 if (!obs.contains(o)) { 5 obs.addElement(o); 6 } 7 }
刪除觀察者


1 public synchronized void deleteObserver(Observer o) { 2 obs.removeElement(o); 3 }
提醒所有的觀察者:


1 public void notifyObservers(Object arg) { 2 3 Object[] arrLocal; 4 5 synchronized (this) { 6 7 if (!changed) 8 return; 9 arrLocal = obs.toArray(); 10 clearChanged(); 11 } 12 13 for (int i = arrLocal.length-1; i>=0; i--) 14 ((Observer)arrLocal[i]).update(this, arg); 15 }


1 這裡先判斷狀態是否發生了改變,是就趕快地通知所有的觀察者的Update() 2 接下來是關於狀態位的改變:


1 public synchronized boolean hasChanged() { 2 return changed; 3 } 4 5 6 protected synchronized void setChanged() { 7 changed = true; 8 }
那麼Observer又是如何改變滴呢?


1 public interface Observer { 2 3 void update(Observable o, Object arg); 4 }
好好地咀嚼下JDK 設計的好處吧:
通過狀態為來控制其他的改變,當需要notify時就會主動調用Observer的updata方法。
那麼現在開始我們的觀察者模式學習吧
可能對於上面的觀察者我們會直接使用了,所以我們很有必要理解上面的東西的。
那麼這個又該如何實現呢?
先定義一個用於展示的接口:


1 package com.ownwell; 2 3 public interface IDisplay { 4 void display(); 5 }
再去實現主題類:


1 package com.ownwell; 2 3 import java.util.Observable; 4 import java.util.Observer; 5 6 7 8 public class WeatherData extends Observable{ 9 10 private float temperature; 11 private float humidity; 12 private float pressure; 13 public WeatherData() {} 14 15 16 public void setMeasures(float temperatur,float humidity,float pressure) 17 { 18 this.humidity = humidity; 19 this.temperature = temperatur; 20 this.pressure = pressure; 21 22 measureChanged(); 23 } 24 public void measureChanged() 25 { 26 setChanged(); 27 notifyObservers(); 28 //在notifyObservers()裏面會自動調用update 29 30 } 31 32 public float getTemperature() { 33 return temperature; 34 } 35 36 public float getHumidity() { 37 return humidity; 38 } 39 40 public float getPressure() { 41 return pressure; 42 } 43 }
當我們改變這些屬性setMeasures()時就會通知所有的監聽者,其中在Observable的notifyObservers()的有個observer.update(this,arg)是將整個Observable交給了observer對象啊。


1 package com.ownwell; 2 3 import java.util.Observable; 4 import java.util.Observer; 5 6 public class CurrentDisply implements Observer, IDisplay { 7 private float temperature; 8 private float humidity; 9 private float pressure; 10 private Observable observable; 11 12 public CurrentDisply(Observable obs) { 13 this.observable = obs; 14 observable.addObserver(this); 15 } 16 17 @Override 18 public void update(Observable o, Object arg) 19 { 20 if (o instanceof WeatherData) { 21 WeatherData data = (WeatherData) o; 22 this.humidity = data.getHumidity(); 23 this.temperature = data.getTemperature(); 24 this.pressure = data.getPressure(); 25 26 display(); 27 } 28 } 29 30 @Override 31 public void display() { 32 String infomation = "humadity="+this.humidity 33 +"\ttemperature ="+this.temperature 34 +"\tpressure ="+this.pressure; 35 36 37 System.out.println(infomation); 38 } 39 40 } 41 评论这张转发至微博