zoukankan      html  css  js  c++  java
  • 设计模式真香笔记-观察者模式

    观察者模式的介绍

    观察者模式:对象之间一对多依赖,当一个对象改变状态的时候,它的所有依赖都会收到通知并且自动更新。
    这样说可能有些人不能理解,我们来举个生动形象的例子:

    许多人以前会经常订阅杂志,杂志社会定期发杂志给订阅者,当然他也可以取消订阅,那么杂志社就不会继续发杂志给订阅者。

    这个例子里面杂志社就是可观察者,而订阅者就相当于观察者,杂志社定期更新会通知他的所有依赖也就是订阅者。
    再来个图促进理解:
    观察者模式

    利用到的新原则

    • 为交互对象之间的松耦合设计而努力

    观察者模式的例子(气象台布告板例子)

    UML类图

    有空在画图。

    实现代码附带一些解释

    • Subject接口
    /**
     * Subject接口为可观察者(主题)接口
     * @
     */
    public interface Subject {
         /**
          * @param o 传入参数为观察者接口实现对象
          */
         void registerObserver(Observer o);//注册为观察者
         void removeObserver(Observer o);//退出观察者
         void notifyObserevers();//当主题数据改变时及时候通知观察者。
    }
    
    • Observer接口
    public interface Observer {//观察者接口
        void update(float temperature, float humidity,float pressure);//更新数据
    }
    
    
    • display接口
    public interface Display {//显示数据
        void display();
    }
    
    
    • WeatherData(实现可观察接口成为可观察者)
    public class WeatherData implements Subject {
        private ArrayList observers;
        private float temperature;//温度
        private float humidity;//湿度
        private float pressure;//气压
        public WeatherData(){
            observers = new ArrayList();//用于观察者注册的集合
        }
        @Override
        public void registerObserver(Observer o) {
            observers.add(o);
        }
    
        @Override
        public void removeObserver(Observer o) {
            int i = observers.indexOf(o);
            if(i>=0){
                observers.remove(i);
            }
        }
    
        @Override
        public void notifyObserevers() {
            for (Object observer: observers
                 ) {
                Observer observer1 = (Observer) observer;
                observer1.update(temperature,humidity,pressure);
    
            }
        }
        public void measurementsChanged(){//更新通知
            notifyObserevers();
        }
    
        public void setMeasurements(float temperature, float humidity, float pressure) {//改变观察者数据
            this.temperature=temperature;
            this.humidity=humidity;
            this.pressure=pressure;
            measurementsChanged();
        }
        //其他扩展方法
    }
    
    • CurrentConditionDisplay (实现观察者接口成为观察者)
    public class CurrentConditionDisplay implements  Observer,Display {
        private float temperature;
        private float humidity;
        private Subject weatherData;
        public CurrentConditionDisplay(Subject weatherData){//构造方法实现注册为观察者
            this.weatherData=weatherData;
            weatherData.registerObserver(this);
        }
    
        @Override
        public void display() {//显示数据
            System.out.println("CurrentConditionDisplay:"+temperature+"Humidity"+humidity);
        }
    
        @Override
        public void update(float temperature, float humidity, float pressure) {
                this.temperature=temperature;
                this.humidity=humidity;
                display();
        }
    }
    
    • CurrentConditionDisplayM(实现观察者接口成为观察者)
    public class CurrentConditionDisplayM implements  Observer,Display {
        private float temperature;
        private float humidity;
        private float pressure;
        private Subject weatherData;
        public CurrentConditionDisplayM(Subject weatherData){
            this.weatherData=weatherData;
            weatherData.registerObserver(this);
        }
    
        @Override
        public void display() {
            System.out.println("CurrentConditionDisplayM:"+temperature*3+"Humidity"+humidity/2+"pressure"+pressure*4);
        }
    
        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature=temperature;
            this.humidity=humidity;
            this.pressure=pressure;
            display();
        }
    }
    
    • WeatherStation(气象站类也就是测试类)
    public class WeatherStation {
        public static void main(String[] args) {
            WeatherData weatherData = new WeatherData();
           CurrentConditionDisplay currentConditionDisplay = new CurrentConditionDisplay(weatherData);
            CurrentConditionDisplayM currentConditionDisplayM = new CurrentConditionDisplayM(weatherData);
            weatherData.setMeasurements(80,68,29.2f);
           weatherData.setMeasurements(90,100,23);
    
        }
    }
    
    • 打印结果
      观察者模式打印结果

    观察者模式的总结

    可观察者和观察者之间用松耦合的形式结合,可观察者只知道观察者实现了观察者的接口,而不知道观察者具体内容。
    有多个观察者时候,不可以依赖特定的通知次序。
    swing类库中就有很多使用观察者模式的例子,譬如说:点击按钮添加多种监听器,实现不同的功能。

    一些补充

    在java.util 类库中有实现好的观察者模式。Observable.java(可观察者类是类不是接口),在这类里面有一个setchanged()方法用来标记可观察者的状态的事实,那他的意义是什么呢?我们不需要标记就可以更新啊,其实他的作用是为了控制可观察者的更新频率,我们可以通过这个方法实现上面的气象站例子 三天,或者半个月更新一次,没有这个方法,我们没有办法控制,气象站就会实时更新。具体我们可以java.util类库中Observable.java的源码。


    本文参考:《Head First 设计模式》

  • 相关阅读:
    COLLABNET 在中文语言下无法编辑用户信息.
    安装ramdisk有可能使xp3389不能用
    关于23种设计模式的有趣见解
    成绩统计分析系统规划
    编程用开源软件或者免费软件
    ROS设置大全
    禁用TextBox自动填充autocomplete=false
    CollabNet Subversion Server安装与配置
    DbEntry查询表的使用
    BugTracker.Net设置问题
  • 原文地址:https://www.cnblogs.com/narojay/p/10812599.html
Copyright © 2011-2022 走看看