观察者模式

《Head First设计模式》Eric Freeman;Elisabeth Freeman;Kathy Sierra;Bert Bates
中国电力出版社
ISBN:9787508353937

观察者模式-定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

观察者模式

设计原则-为了交互对象之间的送耦合设计而努力。对于观察者模式而言,改变主题或观察者其中一方,并不会影响另一方。因为两者是送耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。

天气预报主题(WeatherData)需要监控temperature,humidity和pressure三个数据,如果发生变化,需要通知相应的观察者。

示例代码:
Subject.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public interface Subject { 
  4.     void registerObserver(Observer o); 
  5.      
  6.     void removeObserver(Observer o); 
  7.      
  8.     void notifyObservers(); 


Observer.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public interface Observer { 
  4.     void update(float temp,float humidity, float pressure); 


DisplayElement.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public interface DisplayElement { 
  4.     void display(); 


WeatherData.java

  
  
  1. package net.dp.observer; 
  2.  
  3. import java.util.ArrayList; 
  4.  
  5. public class WeatherData implements Subject { 
  6.     private ArrayList<Observer> observers; 
  7.     private float temperature; 
  8.     private float humidity; 
  9.     private float pressure; 
  10.  
  11.     public WeatherData() { 
  12.         observers = new ArrayList<Observer>(); 
  13.     } 
  14.  
  15.     public void registerObserver(Observer o) { 
  16.         observers.add(o); 
  17.     } 
  18.  
  19.     public void removeObserver(Observer o) { 
  20.         int i = observers.indexOf(o); 
  21.         if (i >= 0) { 
  22.             observers.remove(i); 
  23.         } 
  24.     } 
  25.  
  26.     public void notifyObservers() { 
  27.         for (int i = 0; i < observers.size(); i++) { 
  28.             Observer observer = (Observer) observers.get(i); 
  29.             observer.update(temperature, humidity, pressure); 
  30.         } 
  31.     } 
  32.  
  33.     public void measurementsChanged() { 
  34.         notifyObservers(); 
  35.     } 
  36.  
  37.     public void setMeasurements(float temperature, float humidity, 
  38.             float pressure) { 
  39.         this.temperature = temperature; 
  40.         this.humidity = humidity; 
  41.         this.pressure = pressure; 
  42.         measurementsChanged(); 
  43.     } 
  44.  
  45.     // other WeatherData methods here 
  46.  
  47.     public float getTemperature() { 
  48.         return temperature; 
  49.     } 
  50.  
  51.     public float getHumidity() { 
  52.         return humidity; 
  53.     } 
  54.  
  55.     public float getPressure() { 
  56.         return pressure; 
  57.     } 


CurrentConditionsDisplay.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public class CurrentConditionsDisplay implements Observer, DisplayElement { 
  4.     private float temperature; 
  5.     private float humidity; 
  6.  
  7.     public CurrentConditionsDisplay(Subject weatherData) { 
  8.         weatherData.registerObserver(this); 
  9.     } 
  10.  
  11.     public void update(float temperature, float humidity, float pressure) { 
  12.         this.temperature = temperature; 
  13.         this.humidity = humidity; 
  14.         display(); 
  15.     } 
  16.  
  17.     public void display() { 
  18.         System.out.println("Current conditions: " + temperature 
  19.                 + "F degrees and " + humidity + "% humidity"); 
  20.     } 


ForecastDisplay.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public class ForecastDisplay implements Observer, DisplayElement { 
  4.     private float currentPressure = 29.92f; 
  5.     private float lastPressure; 
  6.  
  7.     public ForecastDisplay(WeatherData weatherData) { 
  8.         weatherData.registerObserver(this); 
  9.     } 
  10.  
  11.     public void update(float temp, float humidity, float pressure) { 
  12.         lastPressure = currentPressure; 
  13.         currentPressure = pressure; 
  14.  
  15.         display(); 
  16.     } 
  17.  
  18.     public void display() { 
  19.         System.out.print("Forecast: "); 
  20.         if (currentPressure > lastPressure) { 
  21.             System.out.println("Improving weather on the way!"); 
  22.         } else if (currentPressure == lastPressure) { 
  23.             System.out.println("More of the same"); 
  24.         } else if (currentPressure < lastPressure) { 
  25.             System.out.println("Watch out for cooler, rainy weather"); 
  26.         } 
  27.     } 


StatisticsDisplay.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public class StatisticsDisplay implements Observer, DisplayElement { 
  4.     private float maxTemp = 0.0f; 
  5.     private float minTemp = 200
  6.     private float tempSum = 0.0f; 
  7.     private int numReadings; 
  8.  
  9.     public StatisticsDisplay(WeatherData weatherData) { 
  10.         weatherData.registerObserver(this); 
  11.     } 
  12.  
  13.     public void update(float temp, float humidity, float pressure) { 
  14.         tempSum += temp; 
  15.         numReadings++; 
  16.  
  17.         if (temp > maxTemp) { 
  18.             maxTemp = temp; 
  19.         } 
  20.  
  21.         if (temp < minTemp) { 
  22.             minTemp = temp; 
  23.         } 
  24.  
  25.         display(); 
  26.     } 
  27.  
  28.     public void display() { 
  29.         System.out.println("Avg/Max/Min temperature = " 
  30.                 + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp); 
  31.     } 


HeatIndexDisplay.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public class HeatIndexDisplay implements Observer, DisplayElement { 
  4.     float heatIndex = 0.0f; 
  5.  
  6.     public HeatIndexDisplay(WeatherData weatherData) { 
  7.         weatherData.registerObserver(this); 
  8.     } 
  9.  
  10.     public void update(float t, float rh, float pressure) { 
  11.         heatIndex = computeHeatIndex(t, rh); 
  12.         display(); 
  13.     } 
  14.  
  15.     private float computeHeatIndex(float t, float rh) { 
  16.         float index = (float) ((16.923 + (0.185212 * t) + (5.37941 * rh) 
  17.                 - (0.100254 * t * rh) + (0.00941695 * (t * t)) 
  18.                 + (0.00728898 * (rh * rh)) + (0.000345372 * (t * t * rh)) 
  19.                 - (0.000814971 * (t * rh * rh)) 
  20.                 + (0.0000102102 * (t * t * rh * rh)) 
  21.                 - (0.000038646 * (t * t * t)) + (0.0000291583 * (rh * rh * rh)) 
  22.                 + (0.00000142721 * (t * t * t * rh)) 
  23.                 + (0.000000197483 * (t * rh * rh * rh)) 
  24.                 - (0.0000000218429 * (t * t * t * rh * rh)) + 0.000000000843296 * (t 
  25.                 * t * rh * rh * rh)) - (0.0000000000481975 * (t * t * t * rh 
  26.                 * rh * rh))); 
  27.         return index; 
  28.     } 
  29.  
  30.     public void display() { 
  31.         System.out.println("Heat index is " + heatIndex); 
  32.     } 


WeatherStation.java

  
  
  1. package net.dp.observer; 
  2.  
  3. public class WeatherStation { 
  4.  
  5.     public static void main(String[] args) { 
  6.         WeatherData weatherData = new WeatherData(); 
  7.  
  8.         new CurrentConditionsDisplay(weatherData); 
  9.         new StatisticsDisplay(weatherData); 
  10.         new ForecastDisplay(weatherData); 
  11.         new HeatIndexDisplay(weatherData); 
  12.  
  13.         weatherData.setMeasurements(806530.4f); 
  14.         System.out.println("======================"); 
  15.         weatherData.setMeasurements(827029.2f); 
  16.         System.out.println("======================"); 
  17.         weatherData.setMeasurements(789029.2f); 
  18.     } 


《Head First Design Pattern》源代码下载 http://zhangjunhd.blog.51cto.com/113473/69908

本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/54836

你可能感兴趣的:(观察者模式)