定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。
l 为了交互对象之间的松耦合设计而努力。
松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖程度降到了最低。
1 Subject.java
package weatherstation.interf;
public interface Subject {
/**
* 注册观察者
* @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);
}
}