• HeadFirst设计模式之观察者模式


    一、什么是观察者模式

    观察者模式定义了一系列对象间一对多的关系,当主题对象的状态发生变化时,会通知所有观察者

    二、自定义观察模式

    1.

    2.

    1 package headfirst.designpatterns.observer.weather;
    2 
    3 public interface Subject {
    4     public void registerObserver(Observer o);
    5     public void removeObserver(Observer o);
    6     public void notifyObservers();
    7 }

    3.

    1 package headfirst.designpatterns.observer.weather;
    2 
    3 public interface Observer {
    4     public void update(float temp, float humidity, float pressure);
    5 }

    4.

     1 package headfirst.designpatterns.observer.weather;
     2 
     3 import java.util.*;
     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 (Observer observer : observers) {
    28             observer.update(temperature, humidity, pressure);
    29         }
    30     }
    31     
    32     public void measurementsChanged() {
    33         notifyObservers();
    34     }
    35     
    36     public void setMeasurements(float temperature, float humidity, float pressure) {
    37         this.temperature = temperature;
    38         this.humidity = humidity;
    39         this.pressure = pressure;
    40         measurementsChanged();
    41     }
    42 
    43     public float getTemperature() {
    44         return temperature;
    45     }
    46     
    47     public float getHumidity() {
    48         return humidity;
    49     }
    50     
    51     public float getPressure() {
    52         return pressure;
    53     }
    54 
    55 }

    5.

     1 package headfirst.designpatterns.observer.weather;
     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     private WeatherData weatherData;
     9 
    10     public StatisticsDisplay(WeatherData weatherData) {
    11         this.weatherData = weatherData;
    12         weatherData.registerObserver(this);
    13     }
    14 
    15     public void update(float temp, float humidity, float pressure) {
    16         tempSum += temp;
    17         numReadings++;
    18 
    19         if (temp > maxTemp) {
    20             maxTemp = temp;
    21         }
    22  
    23         if (temp < minTemp) {
    24             minTemp = temp;
    25         }
    26 
    27         display();
    28     }
    29 
    30     public void display() {
    31         System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
    32             + "/" + maxTemp + "/" + minTemp);
    33     }
    34 }

    6.

    package headfirst.designpatterns.observer.weather;
    
    public interface DisplayElement {
        public void display();
    }

    7.

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

    8.

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

    9.

     1 package headfirst.designpatterns.observer.weather;
     2 
     3 public class WeatherStation {
     4 
     5     public static void main(String[] args) {
     6         WeatherData weatherData = new WeatherData();
     7     
     8         CurrentConditionsDisplay currentDisplay = 
     9             new CurrentConditionsDisplay(weatherData);
    10         StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
    11         ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    12 
    13         weatherData.setMeasurements(80, 65, 30.4f);
    14         weatherData.setMeasurements(82, 70, 29.2f);
    15         weatherData.setMeasurements(78, 90, 29.2f);
    16     }
    17 }

    10.

     1 package headfirst.designpatterns.observer.weather;
     2 
     3 public class WeatherStationHeatIndex {
     4 
     5     public static void main(String[] args) {
     6         WeatherData weatherData = new WeatherData();
     7         CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
     8         StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
     9         ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    10         HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
    11 
    12         weatherData.setMeasurements(80, 65, 30.4f);
    13         weatherData.setMeasurements(82, 70, 29.2f);
    14         weatherData.setMeasurements(78, 90, 29.2f);
    15     }
    16 }

    三、Java.util.Observable

    1.

    1 package headfirst.designpatterns.observer.weatherobservable;
    2 
    3 public interface DisplayElement {
    4     public void display();
    5 }

    2.

     1 package headfirst.designpatterns.observer.weatherobservable;
     2     
     3 import java.util.Observable;
     4     
     5 public class WeatherData extends Observable {
     6     private float temperature;
     7     private float humidity;
     8     private float pressure;
     9     
    10     public WeatherData() { }
    11     
    12     public void measurementsChanged() {
    13         setChanged();
    14         notifyObservers();
    15     }
    16     
    17     public void setMeasurements(float temperature, float humidity, float pressure) {
    18         this.temperature = temperature;
    19         this.humidity = humidity;
    20         this.pressure = pressure;
    21         measurementsChanged();
    22     }
    23     
    24     public float getTemperature() {
    25         return temperature;
    26     }
    27     
    28     public float getHumidity() {
    29         return humidity;
    30     }
    31     
    32     public float getPressure() {
    33         return pressure;
    34     }
    35 }

    3.

     1 package headfirst.designpatterns.observer.weatherobservable;
     2 
     3 import java.util.Observable;
     4 import java.util.Observer;
     5 
     6 public class StatisticsDisplay implements Observer, DisplayElement {
     7     private float maxTemp = 0.0f;
     8     private float minTemp = 200;
     9     private float tempSum= 0.0f;
    10     private int numReadings;
    11 
    12     public StatisticsDisplay(Observable observable) {
    13         observable.addObserver(this);
    14     }
    15 
    16     public void update(Observable observable, Object arg) {
    17         if (observable instanceof WeatherData) {
    18             WeatherData weatherData = (WeatherData)observable;
    19             float temp = weatherData.getTemperature();
    20             tempSum += temp;
    21             numReadings++;
    22 
    23             if (temp > maxTemp) {
    24                 maxTemp = temp;
    25             }
    26  
    27             if (temp < minTemp) {
    28                 minTemp = temp;
    29             }
    30 
    31             display();
    32         }
    33     }
    34 
    35     public void display() {
    36         System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
    37             + "/" + maxTemp + "/" + minTemp);
    38     }
    39 }

    4.

     1 package headfirst.designpatterns.observer.weatherobservable;
     2 
     3 import java.util.Observable;
     4 import java.util.Observer;
     5 
     6 public class HeatIndexDisplay implements Observer, DisplayElement {
     7     float heatIndex = 0.0f;
     8 
     9     public HeatIndexDisplay(Observable observable) {
    10         observable.addObserver(this);
    11     }
    12 
    13     public void update(Observable observable, Object arg) {
    14         if (observable instanceof WeatherData) {
    15             WeatherData weatherData = (WeatherData)observable;
    16             float t = weatherData.getTemperature();
    17             float rh = weatherData.getHumidity();
    18             heatIndex = (float)
    19                 (
    20                 (16.923 + (0.185212 * t)) + 
    21                 (5.37941 * rh) - 
    22                 (0.100254 * t * rh) + 
    23                 (0.00941695 * (t * t)) + 
    24                 (0.00728898 * (rh * rh)) + 
    25                 (0.000345372 * (t * t * rh)) - 
    26                 (0.000814971 * (t * rh * rh)) +
    27                 (0.0000102102 * (t * t * rh * rh)) - 
    28                 (0.000038646 * (t * t * t)) + 
    29                 (0.0000291583 * (rh * rh * rh)) +
    30                 (0.00000142721 * (t * t * t * rh)) + 
    31                 (0.000000197483 * (t * rh * rh * rh)) - 
    32                 (0.0000000218429 * (t * t * t * rh * rh)) +
    33                 (0.000000000843296 * (t * t * rh * rh * rh)) -
    34                 (0.0000000000481975 * (t * t * t * rh * rh * rh)));
    35             display();
    36         }
    37     }
    38 
    39     public void display() {
    40         System.out.println("Heat index is " + heatIndex);
    41     }
    42 }

    5.

     1 package headfirst.designpatterns.observer.weatherobservable;
     2 
     3 import java.util.Observable;
     4 import java.util.Observer;
     5 
     6 public class ForecastDisplay implements Observer, DisplayElement {
     7     private float currentPressure = 29.92f;  
     8     private float lastPressure;
     9 
    10     public ForecastDisplay(Observable observable) {
    11         observable.addObserver(this);
    12     }
    13 
    14     public void update(Observable observable, Object arg) {
    15         if (observable instanceof WeatherData) {
    16             WeatherData weatherData = (WeatherData)observable;
    17             lastPressure = currentPressure;
    18             currentPressure = weatherData.getPressure();
    19             display();
    20         }
    21     }
    22 
    23     public void display() {
    24         System.out.print("Forecast: ");
    25         if (currentPressure > lastPressure) {
    26             System.out.println("Improving weather on the way!");
    27         } else if (currentPressure == lastPressure) {
    28             System.out.println("More of the same");
    29         } else if (currentPressure < lastPressure) {
    30             System.out.println("Watch out for cooler, rainy weather");
    31         }
    32     }
    33 }

    6.

     1 package headfirst.designpatterns.observer.weatherobservable;
     2 
     3 public class WeatherStation {
     4 
     5     public static void main(String[] args) {
     6         WeatherData weatherData = new WeatherData();
     7         
     8         CurrentConditionsDisplay currentConditions = new CurrentConditionsDisplay(weatherData);
     9         StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
    10         ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    11 
    12         weatherData.setMeasurements(80, 65, 30.4f);
    13         weatherData.setMeasurements(82, 70, 29.2f);
    14         weatherData.setMeasurements(78, 90, 29.2f);
    15     }
    16 }

    四、Swing中的观察者模式

    1.

     1 package headfirst.observer.swing;
     2     
     3 import java.awt.*;
     4 import java.awt.event.*;
     5 import javax.swing.*;
     6 import javax.swing.event.*;
     7     
     8 public class SwingObserverExample {
     9     JFrame frame;
    10     
    11     public static void main(String[] args) {
    12         SwingObserverExample example = new SwingObserverExample();
    13         example.go();
    14     }
    15     
    16     public void go() {
    17         frame = new JFrame();
    18 
    19         JButton button = new JButton("Should I do it?");
    20         button.addActionListener(new AngelListener());
    21         button.addActionListener(new DevilListener());
    22         frame.getContentPane().add(BorderLayout.CENTER, button);
    23 
    24         // Set frame properties 
    25         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    26         frame.getContentPane().add(BorderLayout.CENTER, button);
    27         frame.setSize(300,300);
    28         frame.setVisible(true);
    29     }
    30     
    31     class AngelListener implements ActionListener {
    32         public void actionPerformed(ActionEvent event) {
    33             System.out.println("Don't do it, you might regret it!");
    34         }
    35     }
    36 
    37     class DevilListener implements ActionListener {
    38         public void actionPerformed(ActionEvent event) {
    39             System.out.println("Come on, do it!");
    40         }
    41     }
    42 }
  • 相关阅读:
    深入理解redis数据类型
    js获取带#号链接后的参数
    js对象深拷贝与浅拷贝
    VUE + ElementUI 从搭建到运行
    python 输入一个整数,判断其是否既是3的倍数,又是5的倍数
    输入一个三位整数,顺序打印个位、十位、百位上的数
    python 输入三个整数,按照从小到大的顺序打印
    python 运算符与分支结构
    python 变量定义
    python 环境安装
  • 原文地址:https://www.cnblogs.com/shamgod/p/5254446.html
Copyright © 2020-2023  润新知