背景介绍:需要建设一个气象站,目前有一个WeatherData对象,会负责追踪目前天气状况(温度,湿度,气压)。现要求建立一个应用,有三种布告板,分别显示目前的状况,气象统计及简单的预报。当WeatherData对象获取最新测量数据时,三种布告板必须实时更新。而且可扩展布告板。
WeatherData源文件:
第一想法的错误示范:
这样会导致不能很好拓展:
解决方案:
使用观察者模式:出版者+订阅者=观察者模式
例如:定报纸,中介等
参照此类图,可以设计出气象站的类图:
具体实现代码:
subject
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
public void notifyObservers();
}
observer
public interface Observer {
void update(float temp, float humidity, float perssure);
}
display
public interface DispalyElement {
void dispaly();
}
WeatherData
public class WeatherData implements Subject {
private float temperature;
private float humidity;
private float pressure;
private ArrayList<Observer> observers;
public WeatherData() {
observers = new ArrayList();
}
public void registerObserver(Observer o) {//注册
observers.add(o);
}
public void removeObserver(Observer o) {//取消注册
observers.remove(o);
}
public void notifyObservers() {//通知所有
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void messurementsChanged() {数据更新
notifyObservers();
}
public void setMessurements(float temperature, float humidity, float pressure) {模拟天气获取
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
messurementsChanged();
}
}
创建当前天气布告板
public class CurrentConditionDisplay implements Observer, DispalyElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);//注册此布告板
}
public void dispaly() {
System.out.println("current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}
public void update(float temp, float humidity, float perssure) {//变更执行
this.temperature = temp;
this.humidity = humidity;
dispaly();
}
}
其他三个或拓展也类似处理。
启动工作站
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData);
weatherData.setMessurements(80, 65, 30.4f);
}
}
运行结果:
总结:
观察者模式--在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。