使用java.util.Observable类和java.util.Observer接口实现观察者模式气象站(拉、推均实现,自己也可以按照它的实现方法扩展)
拉:也就是观察者来决定接到“可观察者”类通知时获取“可观察者”的哪些变化。调用方法notifyObservers();
推:“可观察者”类通知观察者时传递给观察者自身所有的变化。调用方法notifyObservers(Object arg);
import java.util.Observable;
import java.util.Observer;
//此类实现的是“拉”的发式,继承java.util.Observable类
public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;
//构造器不需要为了记住观察者们而建立数据结构了
public WeatherData() { }
public void measurementsChanged() {
setChanged();//指示可观察者状态已改变(可以由状态是否改变决定是否通知观察者,很容易,自己实现就行)
notifyObservers();//没有调用传送数据对象,表示采用“拉”的做法
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
//以下不是新方法,而是为了使用“拉”的做法
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
import java.util.Observable;
import java.util.Observer;
//实现java.util.Observer接口,成为观察者
public class CurrentConditionsDisplay implements Observer, DisplayElement {
Observable observable;
private float temperature;
private float humidity;
//构造器需要Observable 作为参数,并将本对象登记为观察者
public CurrentConditionsDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
//改变update()方法,增加Observable 和数据对象为参数
public void update(Observable obs, Object arg) {
if (obs instanceof WeatherData) {
WeatherData weatherData = (WeatherData)obs;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}
public void display() {
System.out.println("Current conditions: " + temperature
+ "F degrees and " + humidity + "% humidity");
}
}
注意:java.util.Observable是一个类而不是接口,而且还没有实现任何接口。它本身的实现有很多问题,限制了它的使用和复用。由于它是个类,所以我们只能继承,java不允许多继承,所以限制了其复用潜力。而且setChanged()方法被保护起来(被定义成protected),这就意味着除非继承,否则无法创建实例并组合到自己的对象中,这就违背了设计原则“多用组合,少用继承”。