• 观察者模式(二)--《Head First DesignPattern》


    我们用Java中自带的观察者模式接口来重写前面的例子。

    先看一下类图:

    这里用到了一个setChanged函数,它用来标记状态已经改变的事实,好让notifyObservers()知道当它调用时就应该更新观察者。如果调用notifyObservers()之前没有先调用setChanged(),观察者就不会被通知到。setChanged()方法可以让你在更新观察者时,有更大的弹性,你可以适当地通知观察者。

    Observable内部是这样的结构:

    setChanged(){
     changed = true;      
    }
    
    notifyObservers(Object arg){
     if (changed){
       for every observer on the list{
          call update(this, arg)       
      } } } notifyObservers(){ notifyObservers(
    null); }

     注意这里是继承Observable类,而不是接口

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

    观察者实现Observer接口,

     1 package headfirst.observer.weatherobservable;
     2 
     3 import java.util.Observable;
     4 import java.util.Observer;
     5     
     6 public class CurrentConditionsDisplay implements Observer, DisplayElement {
     7     Observable observable;
     8     private float temperature;
     9     private float humidity;
    10     
    11     public CurrentConditionsDisplay(Observable observable) {
    12         this.observable = observable;
    13         observable.addObserver(this);
    14     }
    15     
    16     public void update(Observable obs, Object arg) {
    17         if (obs instanceof WeatherData) {
    18             WeatherData weatherData = (WeatherData)obs;
    19             this.temperature = weatherData.getTemperature();
    20             this.humidity = weatherData.getHumidity();
    21             display();
    22         }
    23     }
    24     
    25     public void display() {
    26         System.out.println("Current conditions: " + temperature 
    27             + "F degrees and " + humidity + "% humidity");
    28     }
    29 }

    ForecastDisplay

     1 package headfirst.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 }
     1 package headfirst.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 }

    main函数

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

    这里还是要注意几点:

    1. java.util.Observable是一个“类”而不是一个“接口”,所以我们的类必须继承它,这带来的问题就是Java中只有单继承,所以这限制了Observable的复用能力。而且Observable中的setChanged是被设置为protected的,所以除非你继承自Observable,否则你无法创建Observable实例并把它组合到我们的对象中来。如果实在不行,还是建立我们自己实现一套自己的接口,类似于第一篇所说的。
    2. Java中的Swing的API就用到了观察者模式。例如我们有一个JButton对象,然后给他设置监听器。这里的监听器就是一个Observer,而JButton就是一个主题。当在JButton上有对应的事件发生的时候,例如点击,那么就会通知监听器,调用类似于update的方法,其实就是ActionListener中的actionPerformed()方法。
  • 相关阅读:
    Vue菜单栏权限
    elementUI上传图片回显在编辑
    js数据处理
    js数组去重
    elemetUI中el-checkbox-group经过条件判断选中与不选中的问题
    vue强制更新$forceUpdate()
    SASS @mixin 遇到的坑
    点击锚点浏览器锚点前出现/ 斜杠
    POST 传参
    page.php 引入js文件
  • 原文地址:https://www.cnblogs.com/longshaohang/p/3355894.html
Copyright © 2020-2023  润新知