Headfirst-2 观察者模式

1         Headfirst-2 观察者模式

定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

1.1      模式设计原则

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

松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖程度降到了最低。

 

1.1      例子类图

类图

1.1      例子代码

1 Subject.java

package weatherstation.interf;

 

public interface Subject {

    /**

     * 注册观察者

扫描二维码关注公众号,回复: 9988245 查看本文章

     * @param o

     */

    public void registerObserver(Observer o);

    /**

     * 观察者取消注册

     * @param o

     */

    public void removeObserver(Observer o);

    /**

     * 通知所有的观察者

     */

    public void notifyObservers();

}

2 Observer.java

package weatherstation.interf;

 

public interface Observer {

    /**

     * 所有观察者都必须实现update方法,已实现观察者接口

     * 把观测值传送给观察者

     * @param temp

     * @param humidity

     * @param pressure

     */

    public void update(float temp, float humidity, float pressure);

}

 

3 DisplayElement.java

 

package weatherstation.interf;

 

public interface DisplayElement {

    /**

     * DisplayElement接口只包含了一个方法

     * 也就是display。当布告板需要显示的时候

     * 调用该方法

     */

    public void display();

}

 

4 故障管理

package weatherstation;

 

 

import java.util.*;

 

import weatherstation.interf.Subject;

import weatherstation.interf.Observer;

/**

 * 这个类实现Subject接口

 * 得到气象数据

 * @author rose

 *

 */

public class WeatherData implements Subject {

    private ArrayList observers;//Arraylist来记录观察者,在构造器中建立

    private float temperature;//温度

    private float humidity;//湿度

    private float pressure;//气压

   

    public WeatherData() {

       observers = new ArrayList();

    }

   

    //当注册观察者时,我们把他加到arraylist里即可。

    public void registerObserver(Observer o) {

       observers.add(o);

    }

    //当观察者想取消注册的时候,从arraylist里删除即可。

    public void removeObserver(Observer o) {

       int i = observers.indexOf(o);

       if (i >= 0) {

           observers.remove(i);

       }

    }

   

    //通知每一个观察者,因为观察者实现了update方法,所以我们知道如何通知他。

    public void notifyObservers() {

       for (int i = 0; i < observers.size(); i++) {

           Observer observer = (Observer)observers.get(i);

           observer.update(temperature, humidity, pressure);

       }

    }

    //当从气象站得到更新观测值的时候,我们通知观察者。

    public void measurementsChanged() {

       notifyObservers();

    }

    //设置气象数据,或从装置中读取,或从别的网站中抓取,或赋值即可。

    public void setMeasurements(float temperature, float humidity, float pressure) {

       this.temperature = temperature;

       this.humidity = humidity;

       this.pressure = pressure;

       measurementsChanged();

    }

   

    // other WeatherData methods here

   

    public float getTemperature() {

       return temperature;

    }

   

    public float getHumidity() {

       return humidity;

    }

   

    public float getPressure() {

       return pressure;

    }

}

 

5 CurrentConditionsDisplay.java

package weatherstation;

 

 

import weatherstation.interf.DisplayElement;

import weatherstation.interf.Observer;

import weatherstation.interf.Subject;

/**

 * 布告板

 * @author rose

 *

 */

public class CurrentConditionsDisplay implements Observer, DisplayElement {

    private float temperature;//温度

    private float humidity;//湿度

    private Subject weatherData;//天气情况

   

    /**

     * 构造器需要主题来构造作为注册用

     * @param weatherData

     */

    public CurrentConditionsDisplay(Subject 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

           + "F degrees and " + humidity + "% humidity");

    }

}

6 ForecastDisplay.java

package weatherstation;

 

import java.util.*;

 

import weatherstation.interf.DisplayElement;

import weatherstation.interf.Observer;

 

public class ForecastDisplay implements Observer, DisplayElement {

    private float currentPressure = 29.92f; 

    private float lastPressure;

    private WeatherData weatherData;

 

    public ForecastDisplay(WeatherData weatherData) {

       this.weatherData = weatherData;

       weatherData.registerObserver(this);

    }

 

    public void update(float temp, float humidity, float pressure) {

        lastPressure = currentPressure;

       currentPressure = pressure;

       display();

    }

 

    public void display() {

       System.out.print("Forecast: ");

       if (currentPressure > lastPressure) {

           System.out.println("Improving weather on the way!");

       } else if (currentPressure == lastPressure) {

           System.out.println("More of the same");

       } else if (currentPressure < lastPressure) {

           System.out.println("Watch out for cooler, rainy weather");

       }

    }

}

7 StatisticsDisplay.java

package weatherstation;

 

import java.util.*;

import weatherstation.interf.DisplayElement;

import weatherstation.interf.Observer;

 

public class StatisticsDisplay implements Observer, DisplayElement {

    private float maxTemp = 0.0f;

    private float minTemp = 200;

    private float tempSum= 0.0f;

    private int numReadings;

    private WeatherData weatherData;

 

    public StatisticsDisplay(WeatherData weatherData) {

       this.weatherData = weatherData;

       weatherData.registerObserver(this);

    }

 

    public void update(float temp, float humidity, float pressure) {

       tempSum += temp;

       numReadings++;

 

       if (temp > maxTemp) {

           maxTemp = temp;

       }

 

       if (temp < minTemp) {

           minTemp = temp;

       }

 

       display();

    }

 

    public void display() {

       System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)

           + "/" + maxTemp + "/" + minTemp);

    }

}

8 WeatherStation.java

package weatherstation;

 

import java.util.*;

 

public class WeatherStation {

 

    public static void main(String[] args) {

       //创建一个weatherData数据对象

       WeatherData weatherData = new WeatherData();

   

       //创建一个当前天气情况的显示牌

       CurrentConditionsDisplay currentDisplay =

           new CurrentConditionsDisplay(weatherData);

       //创建一个统计的显示牌

       StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);

       //创建一个预报天气的显示牌

       ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);

 

       //设置气象数据

       weatherData.setMeasurements(80, 65, 30.4f);

       weatherData.setMeasurements(82, 70, 29.2f);

       weatherData.setMeasurements(78, 90, 29.2f);

    }

}

 

发布了20 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/huoran668/article/details/4397882