Head First 观察者模式

来源:互联网 发布:seo整站优化外包服务 编辑:程序博客网 时间:2024/06/13 23:37

观察者模式:

我们先举个例子,我们要做一个气象站。

Weather对象知道如何跟物理气象站联系,以取得更新数据。只要温度、湿度、气压一变,所有显示装置都要重新显示。

public class WeatherData {public void measurementsChanged() {float temp = getTemperatrue();//获取数据float humidity = getHundity();float pressure = getPressure();currentConditionDisplay.update(temp, humidity, pressure);//通知各种显示设备statisticcDisplay.update(temp, humidity, pressure);forecastDisplay.update(temp, humidity, pressure);}}

回想上一篇博客说的要把改变的地方封装起来,而这里各种显示设备调用update函数都是针对具体编程了。而且update参数都一样我们可以针对接口编程,做一个Interface。


于是我们就想到了观察者模式:

定义对象之间的一对多依赖,当一个对象改变状态时,所有依赖者都会收到通知并且自动更新。


用观察者模式去开发气象站,当我们有新的显示设备时,我们完全不用改WeatherData的代码,只需要重新实现一个Observer,注册到Subject中就行了。

这种主题和观察者之前互不影响,两者是松耦合的,只要它们之间的接口不变就行。


设计原则:

为了交互对象之间的松耦合设计而努力。


下面是代码实现:

先是Interface:

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 DiplayElement() {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 notifyObservers() {for(int i=0; i < observers.size(); i++) {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 CurrentConditionDisplay implements Observer, DiplayElement {private float temperature;private float humidity;private Subject weatherData;public CurrentConditionDisplay(Subject weatherData) {this.weatherData = weatherData;weatherData.registerObserver(this);}public void update(float temp, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;display();}public void display() {Syste.out.println("Current conditons: " + temperature + "F degrees and " + humidity)}}


测试程序:

public class WeatherStation {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData);StatisticsDisplay statisticDisplay = new StatisticsDisplay(weatherData);ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);weatherData.setMeasurements(80, 65, 30.4f);weatherData.setMeasurements(82, 70, 29.2f);weatherData.setMeasurements(78, 90, 28.1f);}} 


1 0
原创粉丝点击