Observer pattern
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。
1.为了交互对象之间的松耦合设计而努力
对象和观察者抽象为接口,对象接口中定义三个方法:添加观察者、删除观察者和通知观察者。观察者接口中只有一个方法,更新数据方法。实现对象接口的类中要有保存观察者的数组。继承与观察者接口的子类的构造方法的参数为对象。
对象类(被观察者)
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() { // TODO Auto-generated constructor stub observers = new ArrayList(); } /* * (non-Javadoc) * * @see * com.sprd.pattern.observer.impl.Subject#registerObserver(com.sprd.pattern * .observer.impl.Observer) */ @Override public void registerObserver(Observer o) { // TODO Auto-generated method stub observers.add(o); } /* * (non-Javadoc) * * @see * com.sprd.pattern.observer.impl.Subject#removeObserver(com.sprd.pattern * .observer.impl.Observer) */ @Override public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) observers.remove(o); } /* * (non-Javadoc) * * @see com.sprd.pattern.observer.impl.Subject#notifyObservers() */ @Override public void notifyObservers() { // TODO Auto-generated method stub 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); } /* * (non-Javadoc) */ @Override public void display() { System.out.println(String.format( "Current conditions : %f F degrees and %.0f %% humidity", temperature, humidity)); } /* * (non-Javadoc) */ @Override public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } }
public class ForecastDisplay implements DisplayElement, Observer { private float temperature; private float humidity; private Subject weatherData; public ForecastDisplay(Subject weatherData) { this.weatherData = weatherData; } /* * (non-Javadoc) * * @see com.sprd.pattern.observer.impl.Observer#update(float, float, float) */ @Override public void update(float temp, float humidity, float pressure) { // TODO Auto-generated method stub this.temperature = temp; this.humidity = humidity; } /* * (non-Javadoc) * * @see com.sprd.pattern.observer.impl.DisplayElement#display() */ @Override public void display() { // TODO Auto-generated method stub } }
public class StatisticsDisplay implements DisplayElement, Observer { public StatisticsDisplay(Subject weatherData){ } /* (non-Javadoc) * @see com.sprd.pattern.observer.impl.Observer#update(float, float, float) */ @Override public void update(float temp, float humidity, float pressure) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see com.sprd.pattern.observer.impl.DisplayElement#display() */ @Override public void display() { // TODO Auto-generated method stub } }
public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay( weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } }
显示结果
Current conditions : 80.000000 F degrees and 65 % humidity Current conditions : 82.000000 F degrees and 70 % humidity Current conditions : 78.000000 F degrees and 90 % humidity