美文网首页
设计模式思考之观察者模式

设计模式思考之观察者模式

作者: lhsjohn | 来源:发表于2019-03-03 22:33 被阅读0次

    观察者模式的定义:

    观察者模式定义了对象的一对多依赖,这样一来,让一个对象改变状态时,它的所有依赖者都会收到通知并且会自动更新。

    观察者模式的实例:

    实例:建立一个气象站应用,利用WeatherData对象取得数据,并更新三个布告板:当前状况、气象统计和天气预报,当WeatherObject对象获得最新的测量数据时,三种布告板必须实时更新。

    其实观察者模式可以从订报的角度来理解。
    拿报纸的订阅来举例子:

    1. 报社的业务就是出版报纸
    2. 向某家报社订阅了报纸,只要他们有心得报纸出版,就会给你 送过来。只要你是他们的订户,你就会一直收到新报纸。
    3. 当你不再看报纸的时候,取消订阅,他们就不会再送报纸过来
    4. 只要报社还在运营,就会一直有人向他们订阅报纸或者取消订阅报纸。

    定义观察者模式,类图

    观察者模式类图.png

    任何时候我们都可以增加新的观察者,因为主题唯一依赖的东西是一个实现了Observer接口的对象列表。所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代现有的观察者,主题不会受到任何影响。同样的也可以在任何时候删除某些观察者。

    有新类型的观察者出现时,主题的代码不需要修改。加入我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。

    这里体现了我们的一个设计原则,即为了交互对象之间的松耦合设计而努力。
    松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低。

    基于以上的原则,我们可以得出我们对于该气象站的设计图:

    气象站设计图.png

    下面我们用代码来实现气象站

    让我们从建立接口开始

    Public interface Subject{
    //这两个方法都需要一个观察者作为变量,该观察者是用来注册或者被删除的
        Public void registerObserver(Observer o);
           Public void removeObserver(Observer o);
         //当主题状态改变时,这个方法会被调用,以通知所有的观察者
            Public void notifyObservers();
    }
    
    Public interface Observer{
    //当气象观测值改变时,主题会把这些状态值当做方法的参数,传递给观察者。
     Public void update(float temp,float humidity,float pressure);
    
    }
    
    
    Public interface DisplayElement{
    //当布告板需要显示时,调用此方法。
      Public void display();
    }
    
    

    在WeatherData中实现接口

    Public class WeatherData implements Subject{
    
     Private ArrayList observers;
     Private float temperature;
     Private float humidity;
     Private float pressure;
    
    }
    
    
     Public WeatherData(){
          Ovservers=new ArrayList();
     }
    
     Public void registreObserver(Observer o){
           Observers.add(o);
    
     }
    
     Public void removeObserver(Observer o){
         int i=observers.indexOf(o);
           If(i>=0){
            Observers.remove(i);
         }
     }
    
    Public void notifyObservers(){
      for(int i=0;i<observers.size();i++){
        Observer observer =(Observer) observers.get(i);
        Observer.update(temperature,humidity,pressure);
     }
    }
    
    Public void messurementsChanged(){
     notifyObservers();
    
    }
    
    
    Public void setMeasurements(float temperature,float     humidity,float pressure) {
    
      this.temperature=temperature;
      this.humidity=humidity;
      this.pressure=pressure;
    
    }
    
    //WeatherData的其他方法
    
    }
    
    
    

    现在让我们来建立布告板

    Public class CurrentConditionsDisplay implements Observer ,DisplayElement {
      Private float temperature;
      Private float humidity;
      Private Subject weatherData;
     
      //构造器需要weatherData对象作为注册之用
       Public CurrentConditionsDisplay(Subjecy weatherData){
         this.weatherData =weatherData;
         weatherData.registerObserver(this);
       }
    
      Public void update(float temperature,float humidity,float pressure) {
            this.temperature=temperature;
            this.humidity=humidity;
                Display();
      }
    
      Public void display(){
      
        System.out.println(“Current conditions: “+temperature +”℃ and ” +humidity+ “% humidity”)
         }
       
    }
    
    
    

    最后我们可以建立一个测试程序

    Public class WeatherStation {
     
       Public static void main(String[] args) {
        WeatherData weatherData=new WeatherData();
        CurrentConditionsDisplay currentDisplay =new CurrentConditionsDisplay(weatherData);
    
        weatherData.setMeasurements(24,65,30.4f);
        weatherData.setMeasurements(25,64,29.4f);
        weatherData.setMeasurements(29,59,28.4f);
    
     }
    
    }
    
    
    

    运行程序,即可看到输出结果

    Current conditions: 24 ℃ and 65.0 % humidity

    Current conditions: 25 ℃ and 64.0 % humidity

    Current conditions: 29 ℃ and 59.0 % humidity

    这样一个观察者模式的实例就完成了

    java还有内置的观察者模式,Java API内有内置的观察者模式,java.util包内包含最基本的Observer接口与Observeable类,这和我们的Subject接口和 Observer接口很相似。

    用我们的这个气象站的实现作比较,用java内置的观察者模式是有一点小的差异的,最明显的差异是WeatherData(也就是我们的主题)现在要扩展字Observable类,并继承一些添加、删除、通知观察者的方法。

    下面是收集的一些比较好的有关于观察者模式的博文

    1.观察者模式和Spring的结合 https://blog.csdn.net/zlts000/article/details/53462181?ref=myread

    2.观察者模式与事件监听机制 https://blog.csdn.net/qq_22873427/article/details/77169781

    3.设计模式--观察者模式的思考 https://mrdear.cn/2018/04/20/experience/design_patterns--observer/

    4.设计模式 之 观察者 和监听器的区别 https://blog.csdn.net/xiaoliuliu2050/article/details/73274985

    5观察者模式和Spring的结合 https://blog.csdn.net/zlts000/article/details/53462181?ref=myread

    6.深入理解Javascript中的观察者模式 https://www.jb51.net/article/106119.htm

    作者:lhsjohn

    相关文章

      网友评论

          本文标题:设计模式思考之观察者模式

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