Java 提供了 Observer 模式的默認實現,下面我們就看一下 Java 對 觀察者模式的支持。
Java 對 觀察者模式的支持 主要體現在 Observable 類和 Observer 接口。
(1) Observable 類代表 被觀察者 (java.util.Observable)
主要方法有:
void setChanged(): 設置被觀察者的狀態已經被改變
void addObserver(Observer observer): 添加觀察者
int countObservers()
: 返回所有觀察者的數目
void deleteObserver(Observer observer):刪除指定觀察者
void deleteObservers(): 刪除所有觀察者
boolean hasChanged()
: 被觀察者的狀態是否被改變,如果是則返回true,否則返回false
void notifyObservers() : 通知所有觀察者(沒有參數)
void notifyObservers(Object arg) : 通知所有觀察者(帶參數,參數一般設定爲被改變的屬性)
void clearChanged()
:清除被觀察者狀態的改變(即調用 hasChanged() 時會返回 false)
(2) Observer 接口代表 觀察者 (java.util.Observer )
它只有一個抽象方法需要被具體的觀察者類實現(很重要):
void update(Observable observable, Object arg):當 被觀察者 調用 notifyObservers(*)方法
時,會根據被觀察者的 hasChanged()方法 來判斷 它的狀態是否被改變, 如果被觀察者的狀態被改變了,則
會調用 觀察者 的 update 方法,參數 observable 爲 被觀察者對象, arg 爲調用 notifyObservers(Object arg)時傳入的參數 arg ,如果調用的是 notifyObservers()方法, 則 arg 爲 null( 注意 :應該把這個參數 arg設定爲 被觀察者的 被改變的屬性)。
實例
該實例模擬了燒水的過程,涉及三個對象,Heater(熱水器),Display(顯示器),Alarm(報警器).
模擬過程:爲了便於運行,水的初始化溫度爲90,沸點爲95,顯示器依據熱水器顯示溫度,顯示器顯示溫度爲95時,報警器開始報警。明顯可以看出 Heater是subject ,Display 是它的 Obsrver,同時Display亦是suject,因爲它要被報警器觀察,所以Alarm是Display的Observer.
實現過程:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->import java.util.Observable;
public class Heater extends Observable {
private int temperature;
public int getTemperature() {
return temperature;
}
public void setTemperature(int temperature) {
this.temperature = temperature;
}
public void boilWater() {
for (int i = 90; i < 100; i++) {
temperature = i;
this.setChanged();
this.notifyObservers();
}
}
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public class testObserver {
public static void main(String[] args) {
Heater header = new Heater();
Display display = new Display();
Alarm alarm = new Alarm();
header.addObserver(display);
display.addObserver(alarm);
header.boilWater();
}
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->import java.util.Observable;
import java.util.Observer;
public class Alarm implements Observer {
public void makeAlarm() {
System.out.println("嘀嘀嘀水已經燒開 ");
}
public void update(Observable o, Object arg) {
makeAlarm();
}
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->import java.util.Observable;
import java.util.Observer;
public class Display extends Observable implements Observer {
private String status = "未開";
public void setStatus(String status) {
this.status = status;
}
public void displayTemputer(int temperature) {
if (temperature > 95) {
this.setStatus("沸騰");
this.setChanged();
this.notifyObservers();
}
System.out.println("狀態:" + status + " 現在溫度:" + temperature + "");
}
public void update(Observable o, Object arg) {
displayTemputer(((Heater) o).getTemperature());
}
}