观察者模式定义对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
可以用下面的类图来进行说明:
下面用一个经典的示例来进行具体的说明,假设有一个气象观测站需要收集天气数据并且更新三个布告板(目前状况、气象统计和天气预报),那么我们除了需要观察者接口外还需要一个显示数据的接口,具体的实现如下:
主题接口:
public interface Subject{
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
观察者接口:
public interface Observer{
public void update(float temp,float humidity,float pressure);
}
显示接口:
public interface DisplayElement{
public void display();
}
实现主题接口:
public class WeatherData implements Subject{
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){
observers = new ArrayList();
}
public void registerObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o){
int i = observers.indexOf(o);
if(i >= 0){
observers.remove(i);
}
}
public void notifuObservers(){
for(int i = 0;i < observers.size(); i ++){
Observer observer = (Observer)observers.get(i);
observer.update(temperature,humidity,pressure);
}
}
public void measurementsChanged(){
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
接下来就可以实现布告板,具体实现如下:
public class CurrentConditionsDisplay implements Observer, DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature,float humidity,float pressure){
this.temperature = temperature;
this.humidity = humidity;
display();
}
}