Posted on 2008-01-15 10:07 
诗特林 阅读(1879) 
评论(2)  编辑  收藏  所属分类: 
DesignPattern 
			
			
		 
		 
【Head First设计模式】-Observer模式
 
一、要完成的任务
此系统中的三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)。
 
二、Observer模式
 
1、定义观察者模式
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
 
2.设计气象站
 
三、代码实现
 
1.定义接口
 
(1)Subject接口
Subject.java
package com.sterning.ch2_observer;


public interface Subject 
{
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObservers();
}

 
 
(2)Observer接口
Observer.java
package com.sterning.ch2_observer;


public interface Observer 
{
    public void update(float temp,float humidity,float pressure);
}

 
 
(3)Displayment接口
Displayment.java
package com.sterning.ch2_observer;


public interface Displayment 
{
    public void display();
}

 
 
  
2.实现接口
 
(1)WeatherData
WeatherData.java
package com.sterning.ch2_observer;

import java.util.ArrayList;


public class WeatherData implements Subject 
{
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;
    

    public WeatherData()
{
        observers=new ArrayList();
    }
    

    public void notifyObservers() 
{

        for(int i=0;i<observers.size();i++)
{
            Observer observer=(Observer)observers.get(i);
            observer.update(temperature, humidity, pressure);
        }
    }


    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 measurementsChanged()
{
        notifyObservers();
    }

    public void setMeasurements(float temperature,float humidity,float pressure)
{
        this.temperature=temperature;
        this.humidity=humidity;
        this.pressure=pressure;
        measurementsChanged();
    }
}

 
 
(2)CurrentConditionsDisplay
CurrentConditionsDisplay.java
package com.sterning.ch2_observer;


public class CurrentConditionsDisplay implements Observer, Displayment 
{
    private float temperature;
    private float humidity;
    private Subject weatherData;
    

    public CurrentConditionsDisplay(Subject weatherData)
{
        this.weatherData=weatherData;
        weatherData.registerObserver(this);
    }
    

    public void update(float temp, float humidity, float pressure) 
{
        this.temperature=temp;
        this.humidity=humidity;
        display();
    }


    public void display() 
{
        System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity");
    }

}

 
 
(3)StatisticsDisplay
StatisticsDisplay.java
package com.sterning.ch2_observer;

import java.util.*;


public class StatisticsDisplay implements Observer, Displayment 
{
    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);
    }
}

 
 
(4)ForecastDisplay
ForecastDisplay.java
package com.sterning.ch2_observer;

import java.util.*;


public class ForecastDisplay implements Observer, Displayment 
{
    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");
        }
    }
}

 
 
3.实现气象站
WeatherStation.java
package com.sterning.ch2_observer;


public 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);        
        
    }
}
