java.util.Observable类{
addObserver();
deleteObserver();
notifyObserver();
setChanged();
}
java.util.Observer接口{
update();
}
观察者模式提供了java.util.Observable类和java.util.Observer接口。
主题即被观察者。
使用观察者模式时,自己设计一个主题类继承Observable类,设计多个观察者类实现Observer接口。
Observable类中有四个方法,分别用来添加观察者、删除观察者、通知观察者、改变通知状态。
其中通知观察者notifyObservers()方法会调用观察者从Observer接口中实例化的update()方法来通知更新观察者。
改变通知状态setChanged()方法中有一个boolean变量changed,当changed=true时,notifyObservers()会被调用来通知观察者,否者不会通知。
这是setChanged()和notifyObservers()的内部
setChanged(){
changed = true
}
notifyObservers(Object arg){
if(changed){
for every observer on the list{
call update(this,arg)
}
}
}
notifyObservers(){
notifyObservers(null)
}
以下是《Head First设计模式》中的例子
主题WeatherData
package pattern;
import java.util.Observable;
public class WeatherData extends Observable{
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {}
public void measurementChanged(){
setChanged();
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
观察者CurrentConditionDisplay
package pattern;
import java.util.Observable;
public class CurrentConditionDisplay implements DisplayElement, java.util.Observer{
Observable observable;
private float temperable;
private float humidity;
public CurrentConditionDisplay(Observable obs) {
this.observable = obs;
obs.addObserver(this);
}
public void display() {
System.out.println("Current conditions:"+temperable+
"F degrees and "+humidity+"% humidity");
}
public void update(Observable obs, Object arg) {
if(obs instanceof WeatherData){
WeatherData weatherData = (WeatherData) obs;
this.temperable = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}
}
package pattern;
public class Main {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
}
}
通过调用weatherData的setMeasurements()方法传入参数并通知观察者。
在这里例子里,weatherData是主题,即被观察者,他继承Observable类,
CurrentConditionDisplay是观察者,他实现Oberver接口
当被观察更新时,被观察者通过notifyObserver()通知观察者,这时候观察者是被动地更新
同时观察者也可以主动地向被观察者索要资源,即调用weatherData中的getter方法。
java.util.Observable的缺点
Observable是一个类,所以只能设计一个类来继承它。但在Java中不能多重继承,所以当某类想同时具有
Observable类和其他超类的行为时,就会出现麻烦。
这个时候就要自己实现一整套观察者模式。