观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
// 简单实例
import java.util.*;
interface Observer { // 观察者接口
public void update( int value ); // 更新数值
}
interface Subject { // 主题接口
public void registerObserver( Observer o ); // 注册观察者
public void removeObserver( Observer o ); // 去除观察者
public void notifyObservers(); // 通知更新主题的观察者们
}
class SimpleObserver implements Observer { // 单纯观察者
private int value;
private Subject subject; // 主题引用变量
public SimpleObserver( Subject subject ) { // 创建单纯观察者并注册主题
this.subject = subject;
subject.registerObserver( this );
}
public void update( int value ) { //更新数值
this.value = value;
display();
}
public void display() { // 显示内容
System.out.println( "Value: " + value );
}
}
class SimpleSubject implements Subject { // 简单主题
private ArrayList< Observer > observers; // 观察者数组引用变量,记录注册的观察者们
private int value = 0; // 数值变量,用来改变数值
public SimpleSubject() { // 创建主题,并初始化数组
observers = new ArrayList< Observer >();
}
public void registerObserver( 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 ( Observer observer : observers ) {
observer.update( value ); // 更新主题的观察者们内容
}
}
public void setValue( int value ) { // 更新内容
this.value = value;
notifyObservers();
}
}
class Example { // 例子
public static void main( String[] args ) {
SimpleSubject simpleSubject = new SimpleSubject(); // 创建主题
SimpleObserver simpleObserver = new SimpleObserver( simpleSubject ); //创建观察者并注册主题
simpleSubject.setValue( 80 ); // 主题更新内容
}
}
public class Test0525{ // 测试
public static void main( String[] args ){
Example.main( args );
}
}
----------------------------------------------------------------------------------------
E:\java>java Test0525
Value: 80
// 气象站实例
import java.util.*;
interface Subject {
public void registerObserver( Observer o );
public void removeObserver( Observer o );
public void notifyObservers();
}
interface Observer {
public void update( float temp, float humidity, float pressure );
}
interface DisplayElement { // 显示元素
public void display();
}
class WeatherData implements Subject { // 气象资料主题
private ArrayList< Observer > observers;
private float temperature; // 温度
private float humidity; // 湿度
private float pressure; // 压力
public WeatherData() {
observers = new ArrayList< Observer >();
}
public void registerObserver( 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 ( Observer observer : observers ) {
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();
}
public float getTemperature() { // 获得温度
return temperature;
}
public float getHumidity() { // 获得湿度
return humidity;
}
public float getPressure() { // 获得压力
return pressure;
}
}
class CurrentConditionsDisplay implements Observer, DisplayElement { // 当前条件显示
private float temperature;
private float humidity;
private Subject 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" );
}
}
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" ); // 当心凉爽多雨的天气
}
}
}
class HeatIndexDisplay implements Observer, DisplayElement { // 热指数显示
float heatIndex = 0.0f; // 热指数
private WeatherData weatherData;
public HeatIndexDisplay( WeatherData weatherData ) {
this.weatherData = weatherData;
weatherData.registerObserver( this );
}
public void update( float t, float rh, float pressure ) {
heatIndex = computeHeatIndex( t, rh );
display();
}
private float computeHeatIndex( float t, float rh ) { // 计算热指数
float index = ( float )(( 16.923 + ( 0.185212 * t ) + ( 5.37941 * rh ) - ( 0.100254 * t * rh )
+ ( 0.00941695 * ( t * t ) ) + ( 0.00728898 * ( rh * rh ) )
+ ( 0.000345372 * ( t * t * rh ) ) - ( 0.000814971 * ( t * rh * rh ) ) +
( 0.0000102102 * ( t * t * rh * rh ) ) - ( 0.000038646 * ( t * t * t ) ) + ( 0.0000291583 *
( rh * rh * rh ) ) + ( 0.00000142721 * ( t * t * t * rh ) ) +
( 0.000000197483 * ( t * rh * rh * rh ) ) - ( 0.0000000218429 * ( t * t * t * rh * rh ) ) +
0.000000000843296 * ( t * t * rh * rh * rh ) ) -
( 0.0000000000481975 * ( t * t * t * rh * rh * rh ) ) );
return index;
}
public void display() {
System.out.println( "Heat index is " + heatIndex );
}
}
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 );
}
}
class WeatherStation { // 气象站
public static void main( String[] args ) {
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 );
}
}
class WeatherStationHeatIndex { // 气象站热指数
public static void main( String[] args ) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay( weatherData );
StatisticsDisplay statisticsDisplay = new StatisticsDisplay( weatherData );
ForecastDisplay forecastDisplay = new ForecastDisplay( weatherData );
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay( weatherData );
weatherData.setMeasurements( 80, 65, 30.4f );
weatherData.setMeasurements( 82, 70, 29.2f );
weatherData.setMeasurements( 78, 90, 29.2f );
}
}
public class Test0525{
public static void main( String[] args ){
WeatherStation.main( args );
System.out.println();
WeatherStationHeatIndex.main( args );
}
}
-----------------------------------------------------------------
E:\java>java Test0525
Current conditions: 80.0F degrees and 65.0% humidity
Avg/Max/Min temperature = 80.0/80.0/80.0
Forecast: Improving weather on the way!
Current conditions: 82.0F degrees and 70.0% humidity
Avg/Max/Min temperature = 81.0/82.0/80.0
Forecast: Watch out for cooler, rainy weather
Current conditions: 78.0F degrees and 90.0% humidity
Avg/Max/Min temperature = 80.0/82.0/78.0
Forecast: More of the same
Current conditions: 80.0F degrees and 65.0% humidity
Avg/Max/Min temperature = 80.0/80.0/80.0
Forecast: Improving weather on the way!
Heat index is 82.95535
Current conditions: 82.0F degrees and 70.0% humidity
Avg/Max/Min temperature = 81.0/82.0/80.0
Forecast: Watch out for cooler, rainy weather
Heat index is 86.90124
Current conditions: 78.0F degrees and 90.0% humidity
Avg/Max/Min temperature = 80.0/82.0/78.0
Forecast: More of the same
Heat index is 83.64967