美文网首页
JAVA设计模式(2)- 观察者模式

JAVA设计模式(2)- 观察者模式

作者: 小白201808 | 来源:发表于2018-09-15 21:05 被阅读9次

    1.Internet气象站项目:

       1.提供温度,气压和湿度的接口
       2.测量数据更新时需要时通知给第三方
       3.需要设计开放型API,便于其他公司的也能接入点气象站获取数据
    

    2.WeatherDate类

       WeatherData
       
       getTemperature()
       getHumidity()
       getPressure()
       dataChange()     
    

    3.气象站

      当气象站监测到这些数据的变化的时候,就通知dataChange()函数。
    

    方案一:通用的设计方案

    1.设计一个公告板

     CurrentConditions
      
         updata()
         display()
    

    2.设计WeatherData类

       WeatherDate
      
       getTemperature()
       getHumidity()
       getPressure()
       dataChange()  
     当dataChange() 接收到信息的变化的时候,就通知公告板的update()去通知更新数据
    

    代码实现:

    WeatherData

    package com.java.Internetweather_1;
    //相当于一个接口
    public class WeatherData {
            private float temperature;
            private float humidity;
            private float pressure;
            //有了公告板后,我们就可以把它当作一个属性,被接口使用
            private CurrentConditions currentConditions;
            
            public WeatherData(CurrentConditions currentConditions) {
                     this.currentConditions =  currentConditions; 
                
            }
            public float getTemperature() {
                return temperature;
            }
            public float getHumidity() {
                return humidity;
            }
            public float getPressure() {
                return pressure;
            }
           public void dataChange() {
             //当公告板有信息后,我们就调用它
             //temperature, pressure, humidity都是从气象站获取的,所以用get()方法,然后传给公告板的 
               currentConditions.updata(getTemperature(),getPressure(), getPressure());
           }
          //假设气象站有数据变化setData()模拟了气象站,有数据变化并告诉weatherdata有新数据了,然后waetherdata进行数据的更新();
           public void setData(float  temperature, float pressure,float humidity) {
                this.temperature = temperature;
                this.pressure = pressure;
                this.humidity = humidity;
                dataChange();
           }
    }
    
    

    公告板类:CurrentConditions

    package com.java.Internetweather_1;
    
    public class CurrentConditions {
       private float  temperature;
       private float pressure;
       private float humidity;
       
       public void updata( float  temperature, float pressure,float humidity) {
           this.temperature = temperature;
           this.pressure = pressure;
           this.humidity = humidity;
           //当有更新的时候,我们就直接显示
           display();
       }
       
       public void display() {
           System.out.println("****Taday temperature : "+temperature+"****");
           
           System.out.println("****Taday pressure: "+pressure+"****");
           
           System.out.println("****Taday humiduty: "+humidity+"****");
           
       }
    }
    
    

    测试类:InternetWeather

      package com.java.Internetweather_1;
    
    public class InternetWeather {
       public static void main(String[] args) {
           InternetWeather internetWeather = new InternetWeather();
           
            
       }
       public InternetWeather() {
           CurrentConditions currentconditions = new CurrentConditions() ;
           WeatherData weatherData = new WeatherData(currentconditions) ;
           weatherData.setData(16, 160, 20);
       }
    
    }
    
    

    问题:当其他公司也需要气象站的消息,也想要做一个公告板的时候,我们需要在weatherdata类中的大它 change() 里加入其他公告板的初始化;每增加一个新的公司我们的weather data就要重新编译一遍,但是在正常的项目里面,weatherdata往往时是独立的进程,不会动不动就停下重新编译的,所以这个思路的拓展性很不好,所以接下来我们用观察者模式试试。

    解决的问题:

    1)其他第三方公司接入气象站获取数据的问题
    2)在运行时动态添加第三方

    方案二:观察者模式

    了解观察者模式:
        就像定牛奶业务: 
        1)奶站:Subject
        2) 用户:Observer
        
    Subject:登记注册,移除和通知
         <interface>Subject
         registerObserver()
         removeObserver()
         notifyObserver()
         
    Observer:接收输入
           <interface>Observer
           update()
    观察者模式:对象之间多对一依赖关系的一种设方案,被依赖的对象Subject ,依赖的对象是Observer,Subject通知Observer的变化
    

    1)WeatherDataSubject

       //在原来的类中添加三个方法:登记注册,移除和通知,这里的观察者是公告板
        registerObserver()
        removeObserver()
        notifyObservers()
        
        getTemperature()
        getHumidity()
        getPressure()
        dataChange()  
    

    2)CurrentConditionObservers

    Updata()
    display()         
    //当公告板有增加或删除时,就会通过Updatable()告诉 WeatherDataSubject去登记注册,或移除
    //当WeatherDataSubject 有数据变化的时候,就通过 notifyObservers()告诉CurrentConditionObservers去display();
    

    代码实现:

    1)Observer接口:

    package com.java.internetweatherObservermode;
    
    public interface Observer {
        public void update( float  temperature, float pressure,float humidity) ;
            
      }
    
    

    2)Subject接口:

    package com.java.internetweatherObservermode;
    
    public interface Subject {
        public void registerObserver(Observer o);
        public void remodeObserver(Observer o);
        public void notifyObserver();
    }
    

    3)当前公告板类

    package com.java.internetweatherMode;
    
    import com.java.internetweatherObservermode.Observer;
    
    //实现Observer接口(观察者)
    public class CurrentConditions implements Observer{
        private float  temperature;
        private float pressure;
        private float humidity;
        @Override
        public void update(float temperature, float pressure, float humidity) {
            this.temperature = temperature;
            this.pressure = pressure;
            this.humidity = humidity;
            //当有更新的时候,我们就直接显示
            display();
        }
        public void display() {
            System.out.println("****Taday temperature : "+temperature+"****");
            
            System.out.println("****Taday pressure: "+pressure+"****");
            
            System.out.println("****Taday humiduty: "+humidity+"****");
            
        }
    
    }
    

    4)预测天气公告板类

    package com.java.internetweatherMode;
    
    import com.java.internetweatherObservermode.Observer;
    
    //另外一个观察者
    
    public class ForcastConditions implements Observer {
        private float  temperature;
        private float pressure;
        private float humidity;
        @Override
        public void update(float temperature, float pressure, float humidity) {
            this.temperature = temperature;
            this.pressure = pressure;
            this.humidity = humidity;
            //当有更新的时候,我们就直接显示
            display();
            
        }
        public void display() {
            System.out.println("****Tomorrow temperature : "+(temperature+Math.random())+"****");
            
            System.out.println("****Tomorrow pressure: "+(pressure+10*Math.random())+"****");
            
            System.out.println("****Tomorrow humiduty: "+(humidity+Math.random())+"****");
            
        }
    }
    
    

    5)天气数据类(数据的提供者,
    实现Subject接口)

    package com.java.internetweatherMode;
    
    import java.util.ArrayList;
    
    
    import com.java.internetweatherObservermode.Observer;
    import com.java.internetweatherObservermode.Subject;
    //实现Subject接口
    public class WeatherDataSt implements Subject {
        private float temperature;
        private float humidity;
        private float pressure;
        //因为我们不知道以后观察者有点多少,所以我们使用ArrayList集合,完成相应的操作
        private ArrayList<Observer>  observers;
        //有了公告板后,我们就可以把它当作一个属性,被接口使用
        private CurrentConditions currentConditions;
        //在构造函数里将观察者初始化
        public WeatherDataSt( ) {
             observers = new ArrayList<Observer>();
            
        }
        @Override
        public void registerObserver(Observer o) {
            
              observers.add(o);
        }
        @Override
        public void remodeObserver(Observer o) {
            
             if(observers.contains(o))
             {
                 observers.remove(o);
             }
        }
        @Override
        public void notifyObserver() {
                        for(int i = 0 ; i < observers.size(); i++ ) {
                    observers.get(i).update(getTemperature(), getPressure(), getHumidity()); 
                }
        }
    
        public float getTemperature() {
            return temperature;
        }
        public float getHumidity() {
            return humidity;
        }
        public float getPressure() {
            return pressure;
        }
       public void dataChange() {
         //当有新的数据之后,我们就调用 notifyObserver() 
           notifyObserver() ;
       }
      //假设气象站有数据变化setData()模拟了气象站,有数据变化并告诉weatherdata有新数据了,然后waetherdata进行数据的更新();
       public void setData(float  temperature, float pressure,float humidity) {
            this.temperature = temperature;
            this.pressure = pressure;
            this.humidity = humidity;
            dataChange();
       }
    
    }
    

    6)测试类:

    package com.java.internetweatherMode;
    
    public class InternerWeather {
            public static void main(String[] args) {
            
                WeatherDataSt weatherDataSt = new WeatherDataSt( ) ;
                CurrentConditions currentconditions = new CurrentConditions() ;
                ForcastConditions forcastconditions = new ForcastConditions();
                
                weatherDataSt.registerObserver(forcastconditions);
                weatherDataSt.registerObserver(currentconditions );
                
                weatherDataSt.setData(20, 150, 20);
                System.out.println("删除当前公告板的消息后");
            //此时就可以在这里直接添加或者删除观察者,而不需要在weatherdatast那操作了。           
               weatherDataSt.remodeObserver(currentconditions);
                weatherDataSt.setData(15, 180, 20);
                
                
            }
    }
    
    

    output:

    ****Tomorrow temperature : 20.050391790625735****
    ****Tomorrow pressure: 154.9485208171542****
    ****Tomorrow humiduty: 20.820273884785347****
    ****Taday temperature : 20.0****
    ****Taday pressure: 150.0****
    ****Taday humiduty: 20.0****
    删除当前公告板的消息后
    ****Tomorrow temperature : 15.068996039881723****
    ****Tomorrow pressure: 189.28580553999814****
    ****Tomorrow humiduty: 20.16418761237121****
    

    观察者模式的定义:

    Observer模式是行为模式之一,它的作用是当一个对象的状态反思鞥变化时,能够子自动通知其他关联对象,自动刷新对象的状态。
    Observer模式提供给关联对象一种同步通信的手段,使用某个对象与依赖它的其他对象之间保持状态同步。
    

    个人在极客学院的视频学习笔记

    相关文章

      网友评论

          本文标题:JAVA设计模式(2)- 观察者模式

          本文链接:https://www.haomeiwen.com/subject/jtitnftx.html