观察者模式(Observer Pattern)

本文介绍了一个基于观察者模式的天气应用实例,展示了如何通过观察者模式实现天气数据的实时更新和展示。应用包括天气数据类、多种展示类,如实况展示、热指数展示、统计信息展示和天气预报展示。

观察者接口

package ObserverPattern.Weather;

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

天气数据类(观察者)

package ObserverPattern.Weather;

import java.util.ArrayList;

public class WeatherData implements Subject {

    private ArrayList observers;

    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData(){
        observers=new ArrayList();
        temperature=0;
        humidity=0;
        pressure=0;
    }

    @Override
    public void removeObserver(Observer o) {
        int i=observers.indexOf(o);
        if(i>=0)
            observers.remove(i);
    }

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void notifyObserver() {
        for(int i=0;i<observers.size();i++){
            Observer observer=(Observer) observers.get(i);
            observer.update(temperature,humidity,pressure);
        }
    }

    public void measurementsChanged(){
        notifyObserver();
    }

    public void setMeasurements(float temperature,float humidity,float pressure){
        this.temperature=temperature;
        this.humidity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }
}

展示接口

package ObserverPattern.Weather;

public interface DisplayElement {
    public void display();
}

实况展示类

package ObserverPattern.Weather;

public class CurrentConditionDisplay implements Observer, DisplayElement {

    private float temperature;
    private float humidity;
    private Subject weatherDate;

    public CurrentConditionDisplay(Subject weatherData){
        this.weatherDate=weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        this.temperature=temp;
        this.humidity=humidity;
        display();
    }

    public void display(){
        System.out.println("Current Conditions:"+temperature+" F degrees and "+humidity+"& humidity");
    }
}

热指数展示类

package ObserverPattern.Weather;

public class HeatIndexDisplay implements Observer, DisplayElement {


    private WeatherData weatherData;
    private float heatIndex=0.0f;

    public HeatIndexDisplay(WeatherData weatherData){
        this.weatherData=weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        heatIndex=computeHeatIndex(temp,humidity);
        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;
    }

    @Override
    public void display() {
        System.out.println("Heat index is "+heatIndex);
    }
}

统计信息展示类

package ObserverPattern.Weather;

public class StatisticsDisplay implements Observer, DisplayElement {

    private float min=200;
    private float max=0.0f;
    private float sum=0.0f;
    private int num;
    private WeatherData weatherData;

    public StatisticsDisplay(WeatherData weatherData){
        this.weatherData=weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {

        num++;
        sum+=temp;
        max=Math.max(max,temp);
        min=Math.min(min,temp);
        display();
    }

    @Override
    public void display() {
        System.out.println("Avg/Max/Min temperature="+(sum/num)+"/"+max+"/"+min);
    }
}

天气预报展示类

package ObserverPattern.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);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        lastPressure = currentPressure;
        currentPressure = pressure;
        display();
    }

    @Override
    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
            System.out.println("Watch out for cooler,raniny weather!");
    }
}

客户端

package ObserverPattern.Weather;

public class WeatherStation {

    public static void main(String[] args){
        WeatherData weatherdata=new WeatherData();
        CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay(weatherdata);
        StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherdata);
        ForecastDisplay forecastDisplay=new ForecastDisplay(weatherdata);
        HeatIndexDisplay heatIndexDisplay=new HeatIndexDisplay(weatherdata);

        weatherdata.setMeasurements(80,65,30.4f);
        weatherdata.setMeasurements(82,70,29.2f);
        weatherdata.setMeasurements(78,90,29.2f);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值