zoukankan      html  css  js  c++  java
  • 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. 轮询注册者列表,动态调用注册者更新方法
  • 相关阅读:
    my15_ mysql binlog格式从mixed修改为row格式
    my14_mysql指定时间恢复之模拟从库
    my13_mysql xtrabackup备份的时间点
    必知必会的图论算法
    leetcde37. Sudoku Solver
    leetcode36. Valid Sudoku
    leetcode52. N-Queens II
    leetcode51. N-Queens
    First Missing Positive
    Maximum Gap
  • 原文地址:https://www.cnblogs.com/Lollipop_Hsu/p/11932153.html
Copyright © 2011-2022 走看看