有了观察者你将消息灵通。
气象监测应用的概况
此系统中的三个部分是:
气象站——获取实际气象数据的物理装置
WeatherData对象——追踪来自气象站的数据,并更新布告板
布告板——显示目前天气状况给用户看
出版者+订阅者=观察者模式
主题(Subject)+观察者(Observer)
说明:
1. 主题对象管理某些数据
2. 当主题内数据改变,就会通知观察者。
3. 一旦数据改变,新的数据会以某种形式送到观察者手上
4. 观察者已经订阅(注册)主题以便在主题数据改变时能够收到更新
当你试图勾勒观察者模式时,可以利用报纸订阅服务,以及出版者和订阅者比拟这一切。观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。有多个观察者时,不可以依赖特定的通知次序。
说明:
设计原则——为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低。
实现气象站
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 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 notifyObservers(){
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{
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;
this.pressure = pressure;
}
}
Java内置观察者模式
Observer接口和Obserable接口
Observable是一个“类”,而不是一个接口,所以WeatherData扩展了Observable主题。
public class WeatherData extends Observable{
private float temperature;
private float humidity;
private float pressure;
public WeatherData(){ }
public void measurementsChanged(){
setChanged();
notifyObservers();//采用的做法是“拉”
//notifyObservers(arg)是“推”
}
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;
}
}
public class CurrentConditionsDisplay implements Observer{
Observable observable;
private float temperature;
private float humidity;
public CurrentConditionsDisplay(Observable observable){
this.observable = observable;
observable.addObserver(this);
}
public void update(Observable obs,Object arg){
if(obs instanceof WeatherData){
WeatherData weatherData = (WeatherData)obs;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
}
}
}