HeadFirst设计模式---观察者

表达公式

注册者 + 订阅者 = 观察者模式

设计气象站

气象站接口

/** 
 ** 布告板 
 ** @author lollipop
 ** @since 2019/11/24 
 **/
public interface DisplayElement {   
        /** 显示 **/ 
        void display();
}
/**
 * 观察者
 * @author lollipop
 * @since 2019/11/24
 */
public interface Observer {

    /**
     * 更新
     * @param temperature
     * @param humidity
     * @param pressure
     */
    void update(float temperature,float humidity,float pressure);
}

/**
 * 主题接口
 * @author lollipop
 * @since 2019/11/24
 */
public interface Subject {
    /**
     * 注册
     */
    void registerObserver(Observer o);

    /**
     * 注销
     */
    void removeObserver(Observer o);

    /**
     * 通知
     */
    void notifyObserver();
}

气象实现

/**
 * @author lollipop
 * @since 2019/11/24
 */
@Data
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 display() {
        System.out.println("Current conditions: " + temperature
        + "F degrees and " + humidity + "% humidity");
    }

    /**
     * 更新
     * @param temperature
     * @param humidity
     * @param pressure
     */
    public void update(float temperature, float humidity, float pressure) {
        this.humidity = humidity;
        this.temperature = temperature;
        display();
    }
}
/**
 * @author lollipop
 * @since 2019/11/24
 */
public class ForecastDisplay implements Observer, DisplayElement {

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

    /**
     * 天气数据
     */
    private Subject weatherData;

    /**
     * 显示
     */
    public void display() {
        if (this.pressure < 10.0f) {
            System.out.println("晴天");
        } else if (this.pressure >= 10.0f && this.pressure < 50.0f) {
            System.out.println("多云");
        } else {
            System.out.println("下雨");
        }
    }

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

    /**
     * 更新
     *
     * @param temperature
     * @param humidity
     * @param pressure
     */
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        this.display();
    }
}
/**
 * @author lollipop
 * @since 2019/11/24
 */
public class StatisticsDisplay implements Observer, DisplayElement {
    private float maxTemperatures = 0.00f;
    private float minTemperatures = 0.00f;
    private int count = 0;
    private float totalTemperatures = 0.00f;
    private float avgTemperatures = 0.00f;
    /**
     * 天气数据
     */
    private Subject weatherData;

    /**
     * 显示
     */
    public void display() {
        System.out.println("maxTemperatures: " + maxTemperatures);
        System.out.println("minTemperatures: " + minTemperatures);
        System.out.println("avgTemperatures: " + avgTemperatures);
    }

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

    /**
     * 更新
     *
     * @param temperature
     * @param humidity
     * @param pressure
     */
    public void update(float temperature, float humidity, float pressure) {
        if (this.maxTemperatures < temperature) {
            this.maxTemperatures = temperature;
        }
        if (this.minTemperatures == 0.00f) {
            this.minTemperatures = temperature;
        } else if (this.minTemperatures > temperature) {
            this.minTemperatures = temperature;
        }
        if (temperature > 0) {
            totalTemperatures += temperature;
            avgTemperatures = totalTemperatures / ++count;
        }
        this.display();
    }
}

/**
 * @author lollipop
 * @since 2019/11/24
 */
@Data
public class WeatherData implements Subject {
    /**
     * 注入观察者
     */
    List<Observer> observers = new ArrayList<Observer>(5);
    /**
     * 温度
     */
    private float temperature;
    /**
     * 湿度
     */
    private float humidity;

    /**
     * 气压
     */
    private float pressure;

    public WeatherData() {
    }

    /**
     * 注册
     *
     * @param o
     */
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    /**
     * 注销
     *
     * @param o
     */
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(o);
        }
    }

    /**
     * 通知
     */
    public void notifyObserver() {
        for (Observer one : observers) {
            one.update(temperature, humidity, pressure);
        }
    }

    /**
     * 通知观察者
     */
    public void measurementsChanged() {
        notifyObserver();
    }

    /**
     * 设置数据
     *
     * @param temperature
     * @param humidity
     * @param pressure
     */
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}

气象站运行

/**
 * @author lollipop
 * @since 2019/11/25
 */
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay conditionsDisplay = 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);
    }
}

运行结果

Current conditions: 80.0F degrees and 65.0% humidity
maxTemperatures: 80.0
minTemperatures: 80.0
avgTemperatures: 80.0
多云
Current conditions: 82.0F degrees and 70.0% humidity
maxTemperatures: 82.0
minTemperatures: 80.0
avgTemperatures: 81.0
多云
Current conditions: 78.0F degrees and 90.0% humidity
maxTemperatures: 82.0
minTemperatures: 78.0
avgTemperatures: 80.0
多云

总结

  1. 需要List集合保存注册者
  2. 轮询注册者列表,动态调用注册者更新方法
原文地址:https://www.cnblogs.com/Lollipop_Hsu/p/11932153.html