zoukankan      html  css  js  c++  java
  • 设计模式(2)观察者模式

    观察者模式在主题和观察者之间定义一个一对多的依赖关系,当主题发生变化的时候,就会通知依赖它的对象主题已经发生了变化。观察者可以订阅主题,也可以取消订阅,当它取消订阅之后,主题发生的任何改变都不会通知到它,除非它再次订阅主题。

    这次举得一个例子是气象站和布告栏,气象站用来检测气候的变化,布告栏用来显示气候的变化,不同的布告栏显示不同,当气象站发生变化的时候,通知布告栏气候的变化。

    气象站中有一个集合,存放订阅气象站的公告栏,当气象发生变化的时候,会遍历公告栏集合,通知它们发生了变化。

    公告栏对象中,存放着他们订阅的气象站对象,用于取消订阅和添加订阅。

    下面是自己写的代码示例

    观察者接口

    public interface Observer {
        /**
         * 更新状态
         *
         * @param temp     温度
         * @param humidity 湿度
         * @param pressure 气压
         */
        void update(float temp, float humidity, float pressure);
    
        /**
         * 描述
         */
        void display();
    }

    主题接口

    public interface Subject {
        /**
         * 通知观察者
         */
        void notifyObserver();
    
        /**
         * 订阅主题
         * @param observer 观察者
         */
        void registerdObserver(Observer observer);
    
        /**
         * 取消订阅主题
         * @param observer 观察者
         */
        void removerObserver(Observer observer);
    }

    观察者1

    public class CurrentConditionsDisplay implements Observer {
        /**
         * 温度
         */
        private float template;
        /**
         * 湿度
         */
        private float humidity;
        /**
         * 气压
         */
        private float pressure;
    
        private Subject subject;
    
        public CurrentConditionsDisplay(Subject subject) {
            this.subject = subject;
            this.subject.registerdObserver(this);
        }
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.template = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    
        @Override
        public void display() {
            System.out.println("Current conditions: " + template + "F degrees and " + humidity + "% humidity and " + pressure + " pressure ");
        }
    }

    观察者2

    public class ForecastDisplay implements Observer {
        /**
         * 温度
         */
        private float template;
        /**
         * 湿度
         */
        private float humidity;
        /**
         * 气压
         */
        private float pressure;
    
        private Subject subject;
    
        public ForecastDisplay(Subject subject) {
            this.subject = subject;
            this.subject.registerdObserver(this);
        }
    
        @Override
        public void update(float temp, float humidity, float pressure) {
            this.template = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            display();
        }
    
        @Override
        public void display() {
            System.out.println("Forecast: " + template + "F degrees and " + humidity + "% humidity and " + pressure + " pressure ");
        }
    }

     主题

    public class WeatherData implements Subject {
    
        /**
         * 温度
         */
        private float template;
        /**
         * 湿度
         */
        private float humidity;
        /**
         * 气压
         */
        private float pressure;
        /**
         * 观察者列表
         */
        private List<Observer> observers;
    
        public WeatherData() {
            observers = new ArrayList<>();
        }
    
        /**
         * 通知观察者
         */
        @Override
        public void notifyObserver() {
            for (Observer observer : observers) {
                observer.update(template, humidity, pressure);
            }
        }
    
        /**
         * 订阅主题
         *
         * @param observer 观察者
         */
        @Override
        public void registerdObserver(Observer observer) {
            observers.add(observer);
        }
    
        /**
         * 取消订阅主题
         *
         * @param observer 观察者
         */
        @Override
        public void removerObserver(Observer observer) {
            observers.remove(observer);
        }
    
        /**
         * 观测值发生改变
         *
         * @param template 温度
         * @param humidity 湿度
         * @param pressure 气压
         */
        public void setMeasurements(float template, float humidity, float pressure) {
            this.template = template;
            this.humidity = humidity;
            this.pressure = pressure;
            this.measurementsChange();
        }
    
        /**
         * 观测值发生改变
         */
        public void measurementsChange() {
            this.notifyObserver();
        }
    }

    测试

    public class Main {
    
        public static void main(String[] args) {
            WeatherData weatherData = new WeatherData();
            CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
            ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
            weatherData.setMeasurements(10.1f, 20.2f, 30.3f);
            weatherData.setMeasurements(11.1f, 22.2f, 33.3f);
            weatherData.removerObserver(currentConditionsDisplay);
            weatherData.setMeasurements(11.11f, 22.22f, 33.33f);
        }
    }

    输出

     

    当创建观察者的时候,就将其订阅主题,每次主题发生改变,两个观察者都会接收到主题变化的通知。当观察者取消订阅主题后,主题的改动就不会通知到观察者了。

    观察者模式可以运用到很多地方,最常见的就是邮件或者博客的订阅,当你订阅了这个博客之后,每当有文章更新就会及时通知你。

  • 相关阅读:
    MacBook下java环境的搭建
    Mac 终端下Homebrew的几个常用命令(新手笔记)
    新手学Appium_Python_Client
    【转】pycharm的一些快捷键
    解决YUM下Loaded plugins: fastestmirror Determining fastest mirrors 的问题
    chrome扩展第三方浏览器下载安装
    php异或加密解密算法的实现
    TortoiseGit客户端密钥配置
    CURL重试发送请求
    关于接收POST请求 $GLOBALS['HTTP_RAW_POST_DATA']
  • 原文地址:https://www.cnblogs.com/oeleven/p/10415303.html
Copyright © 2011-2022 走看看