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

来源:互联网 发布:js触发onclick事件 编辑:程序博客网 时间:2024/06/06 15:51

          headfirst书中举了个气象站的例子用来讲解观察者模式。

          气象站包括物理装置检测数据,WeatherData对象获取数据,布告板公布数据。WeatherData就是个被观察者,可以定义多个观察者(布告板)来获取被观察者的数据。观察者模式可以使得依赖于某一对象的依赖者会根据该对象状态改变而自动更新。观察者富有弹性,可以添加可以删除。观察者和被观察者之间也是松耦合,因为被观察者只知道观察者实现了Observer接口,不了解具体实现该接口的类有哪些。

         类图如下:

         

建立3个接口:

Subject:

[java] view plaincopy
  1. public interface Subject {  
  2.   
  3.     public void registerObserver(Observer o); //注册观察者
  4.     public void removeObserver(Observer o);    //删除观察者
  5.     public void notifyObserver();              //发布更新
  6. }  

Observer:

[java] view plaincopy
  1. public interface Observer {  
  2.    public void update(float temp,float humidity,float pressure);  //定义了update方法
  3. }  

DisplayElement:

[java] view plaincopy
  1. public interface DisplayElement {  
  2.     public void display();               //显示方法
  3. }  

在WeatherData中实现Subject接口:

[java] view plaincopy
  1. import java.util.ArrayList;  
  2.   
  3. public class WeatherData implements Subject {  
  4.   
  5.     private ArrayList observers;  
  6.     private float temperature;  
  7.     private float pressure;  
  8.     private float humidity;  
  9.   
  10.     public WeatherData() {  
  11.         observers = new ArrayList();  //加上一个ArrayList来记录观察者,此ArrayList是在构造器中产生的  
  12.     }  
  13.   
  14.     public void registerObserver(Observer o) {  
  15.         observers.add(o);                    //有观察者注册时,将其加到ArrayList后面  
  16.     }  
  17.   
  18.     public void removeObserver(Observer o) {  
  19.         int i = observers.indexOf(o);       //观察者取消注册时,将其从ArrayList中删除  
  20.         if (i >= 0) {  
  21.             observers.remove(i);  
  22.         }  
  23.     }  
  24.   
  25.    //通知每一位观察者
  26.     public void notifyObserver() {  
  27.         for (int i = 0; i < observers.size(); i++) {     //遍历观察者的Arraylist         
  28.             Observer observer = (Observer) observers.get(i);  
  29.             observer.update(temperature, humidity, pressure);//这是核心点之一,观察者在构造的时候,会放入weatherdata对象的arraylist中,所以遍历之后,调用该观察者的update()方法,会更新观察者。也就是发布了更新。 
  30.         }  
  31.     }  
  32.   
  33.     public void measurementsChanged() {  
  34.         notifyObserver();  
  35.     }  
  36.   
  37.     public void setMeasurements(float temperature, float humidity,  
  38.             float pressure) {  
  39.         this.temperature = temperature;  
  40.         this.humidity = humidity;  
  41.         this.pressure = pressure;  
  42.         measurementsChanged();  
  43.     }  
  44.   
  45. }  

 

建立当前天气状况和温度统计的布告板:

当前天气状况:

[java] view plaincopy
  1. package com.lissdy;  
  2.   
  3. public class CurrentDisplay implements Observer,DisplayElement{  
  4.    private float temperature;  
  5.    private float humidity;  
  6.    private Subject weatherData;  
  7.      
  8.    public CurrentDisplay(Subject weatherDate)  
  9.    {  
  10.        this.weatherDate=weatherDate;  
  11.        weatherData.registerObserver(this);  //这里是另一个核心点,把该观察者放入weatherdata中的arraylist中,然后在weatherdata对象中的notifyObservers方法中调用注册的观察者的update()方法,达到发布更新的目的。
  12.    }  
  13.    public void update(float temperature,float humidity,float pressure)  
  14.    {  
  15.        this.temperature=temperature;  
  16.        this.humidity=humidity;  
  17.        display();  
  18.    }  
  19.    public void display()  
  20.    {  
  21.        System.out.println("Current conditions:"+temperature+"degrees"+"humidity"+humidity+"%");  
  22.    }  
  23. }
   

建立一个测试程序:

[java] view plaincopy
  1. package com.lissdy;  
  2.   
  3. public class WeatherStation {  
  4.       
  5.     public static void main(String[] args)  
  6.     {  
  7.        WeatherData weatherData=new WeatherData();   //建立一个WeatherData对象  
  8.        CurrentDisplay currentDisplay=new CurrentDisplay(weatherData);  //建立布告板,并把WeatherData传给它们  
  9.        StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherData);  
  10.          
  11.        weatherData.setMeasurements(806530.4f);  //模拟新的气象测量  
  12.        weatherData.setMeasurements(827029.2f);  
  13.        weatherData.setMeasurements(789029.2f);  
  14.     }  

 在注释中的两个核心点的说明就是观察者模式是如何获取更新的。

首先观察者在构造方法中,把该观察者进行注册,也就是weatherData.registerObserver(this)方法,之后会将该观察者放入weatherData的arraylist中。

在客户端调用的时候,会调用weatherData对象的notifyObservers方法,该方法通过遍历arraylist获取观察者,然后调用该观察者的update()方法,获取更新,并display显示出来。

0 0
原创粉丝点击