背景介绍:需要建设一个气象站,目前有一个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); } }
运行结果:
总结:
观察者模式--在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。