设计模式:观察者

本文介绍了一种基于观察者模式的气象站天气预报系统设计。该系统通过WeatherData类作为天气发布器收集气象站数据,并通知多个观察者如CurrentConditionsDisplay、StatisticsDisplay和ForecastDisplay等显示器更新显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在,我们要模拟气象站观测天气,然后将天气预报给不同的对象去显示的情况。

首先,模拟新建一个气象站。其中WeatherData 看作为一个天气发布器,由WeatherStation 获取信息并传送给WeatherData。由WeatherData去通知各个对象显示。在新建发布器之后,就应该新建发布器要通知的信息的那些显示器。然后注册给WeatherData,让WeatherData知道当有新数据过来的时候通知那些对象进行相应处理。

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);
   }
}

接下来是天气发布器的接口。定义和观察者相关的一些方法。

public interface Subject {
   public void registerObserver(Observer o);
   public void removeObserver(Observer o);
   public void notifyObservers();
}

发布器的实现:每次有新值过来的时候调用measurementsChanged()方法。

measurementsChanged()调用notifyObservers()方法。通知各个显示器进行处理。

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 (Observer observer : observers) {
            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 float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }

}

接下来要实现气温更新(即观察者,这里的观察者定义为一个行为。)。

public interface Observer {
   public void update(float temp, float humidity, float pressure);
}

接下来是显示器。

public interface DisplayElement {
   public void display();
}

最后是各种显示器的实现。

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);
   }
   
   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");
   }
}
public class StatisticsDisplay implements Observer, DisplayElement {
   private float maxTemp = 0.0f;
   private float minTemp = 200;
   private float tempSum= 0.0f;
   private int numReadings;
   private WeatherData weatherData;

   public StatisticsDisplay(WeatherData weatherData) {
      this.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);
   }
}
package designpatterns.observer.weather;

public class ForecastDisplay implements Observer, DisplayElement {
   private float currentPressure = 29.92f;  
   private float lastPressure;
   private WeatherData weatherData;

   public ForecastDisplay(WeatherData weatherData) {
      this.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");
      }
   }
}

我感觉这么些表述意义不明。 观察者应该为 

WeatherData

他观察气象站气温改变,然后通知各个显示器显示。由它获取数据,由它分发数据。

转载于:https://my.oschina.net/marjeylee/blog/806661

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值