《Head First设计模式》Eric Freeman;Elisabeth Freeman;Kathy Sierra;Bert Bates
中国电力出版社
ISBN:9787508353937
观察者模式-定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
设计原则-为了交互对象之间的送耦合设计而努力。对于观察者模式而言,改变主题或观察者其中一方,并不会影响另一方。因为两者是送耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。
天气预报主题(WeatherData)需要监控temperature,humidity和pressure三个数据,如果发生变化,需要通知相应的观察者。
示例代码:
Subject.java
- package net.dp.observer;
- public interface Subject {
- void registerObserver(Observer o);
- void removeObserver(Observer o);
- void notifyObservers();
- }
Observer.java
- package net.dp.observer;
- public interface Observer {
- void update(float temp,float humidity, float pressure);
- }
DisplayElement.java
- package net.dp.observer;
- public interface DisplayElement {
- void display();
- }
WeatherData.java
- package net.dp.observer;
- import java.util.ArrayList;
- public class WeatherData implements Subject {
- private ArrayList<Observer> observers;
- private float temperature;
- private float humidity;
- private float pressure;
- public WeatherData() {
- observers = new ArrayList<Observer>();
- }
- 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 void notifyObservers() {
- 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();
- }
- // other WeatherData methods here
- public float getTemperature() {
- return temperature;
- }
- public float getHumidity() {
- return humidity;
- }
- public float getPressure() {
- return pressure;
- }
- }
CurrentConditionsDisplay.java
- package net.dp.observer;
- public class CurrentConditionsDisplay implements Observer, DisplayElement {
- private float temperature;
- private float humidity;
- public CurrentConditionsDisplay(Subject weatherData) {
- weatherData.registerObserver(this);
- }
- public void update(float temperature, float humidity, float pressure) {
- this.temperature = temperature;
- this.humidity = humidity;
- display();
- }
- public void display() {
- System.out.println("Current conditions: " + temperature
- + "F degrees and " + humidity + "% humidity");
- }
- }
ForecastDisplay.java
- package net.dp.observer;
- public class ForecastDisplay implements Observer, DisplayElement {
- private float currentPressure = 29.92f;
- private float lastPressure;
- public ForecastDisplay(WeatherData weatherData) {
- weatherData.registerObserver(this);
- }
- public void update(float temp, float humidity, float pressure) {
- lastPressure = currentPressure;
- currentPressure = pressure;
- display();
- }
- public void display() {
- System.out.print("Forecast: ");
- if (currentPressure > lastPressure) {
- System.out.println("Improving weather on the way!");
- } else if (currentPressure == lastPressure) {
- System.out.println("More of the same");
- } else if (currentPressure < lastPressure) {
- System.out.println("Watch out for cooler, rainy weather");
- }
- }
- }
StatisticsDisplay.java
- package net.dp.observer;
- public class StatisticsDisplay implements Observer, DisplayElement {
- private float maxTemp = 0.0f;
- private float minTemp = 200;
- private float tempSum = 0.0f;
- private int numReadings;
- public StatisticsDisplay(WeatherData weatherData) {
- weatherData.registerObserver(this);
- }
- public void update(float temp, float humidity, float pressure) {
- tempSum += temp;
- numReadings++;
- if (temp > maxTemp) {
- maxTemp = temp;
- }
- if (temp < minTemp) {
- minTemp = temp;
- }
- display();
- }
- public void display() {
- System.out.println("Avg/Max/Min temperature = "
- + (tempSum / numReadings) + "/" + maxTemp + "/" + minTemp);
- }
- }
HeatIndexDisplay.java
- package net.dp.observer;
- public class HeatIndexDisplay implements Observer, DisplayElement {
- float heatIndex = 0.0f;
- public HeatIndexDisplay(WeatherData weatherData) {
- weatherData.registerObserver(this);
- }
- public void update(float t, float rh, float pressure) {
- heatIndex = computeHeatIndex(t, rh);
- display();
- }
- private float computeHeatIndex(float t, float rh) {
- float index = (float) ((16.923 + (0.185212 * t) + (5.37941 * rh)
- - (0.100254 * t * rh) + (0.00941695 * (t * t))
- + (0.00728898 * (rh * rh)) + (0.000345372 * (t * t * rh))
- - (0.000814971 * (t * rh * rh))
- + (0.0000102102 * (t * t * rh * rh))
- - (0.000038646 * (t * t * t)) + (0.0000291583 * (rh * rh * rh))
- + (0.00000142721 * (t * t * t * rh))
- + (0.000000197483 * (t * rh * rh * rh))
- - (0.0000000218429 * (t * t * t * rh * rh)) + 0.000000000843296 * (t
- * t * rh * rh * rh)) - (0.0000000000481975 * (t * t * t * rh
- * rh * rh)));
- return index;
- }
- public void display() {
- System.out.println("Heat index is " + heatIndex);
- }
- }
WeatherStation.java
- package net.dp.observer;
- public class WeatherStation {
- public static void main(String[] args) {
- WeatherData weatherData = new WeatherData();
- new CurrentConditionsDisplay(weatherData);
- new StatisticsDisplay(weatherData);
- new ForecastDisplay(weatherData);
- new HeatIndexDisplay(weatherData);
- weatherData.setMeasurements(80, 65, 30.4f);
- System.out.println("======================");
- weatherData.setMeasurements(82, 70, 29.2f);
- System.out.println("======================");
- weatherData.setMeasurements(78, 90, 29.2f);
- }
- }
《Head First Design Pattern》源代码下载 http://zhangjunhd.blog.51cto.com/113473/69908
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/54836