[Design Pattern] Observer

[Design Pattern] Observer

範例參考至 Head First Design Patterns

IObserver

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

ISubject

public interface ISubject {
	public void registerObserver(IObserver o);
	public void removeObserver(IObserver o);
	public void notifyObservers();
}

IDisplayElement

public interface IDisplayElement {
	public void display();
}

CurrentConditionDisplay

public class CurrentConditionsDisplay implements IObserver, IDisplayElement
{
	private float temperature;
	private float humidity;
	private ISubject iWeatherData;
	
	public CurrentConditionsDisplay(ISubject iWeatherData)
	{
		this.iWeatherData = iWeatherData;
		iWeatherData.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");
	}
}

HeatIndexDisplay

public class HeatIndexDisplay implements IObserver, IDisplayElement{
	private float temperature;
	private float humidity;
	private ISubject iWeatherData;
	
	public HeatIndexDisplay(ISubject iWeatherData)
	{
		this.iWeatherData = iWeatherData;
		iWeatherData.registerObserver(this);
	}
	public void update(float temperature, float humidity, float pressure)
	{
		this.temperature = temperature;
		this.humidity = humidity;
		display();
	}
	public void display()
	{
		System.out.println("Heat index is " + computeHeatIndex(this.temperature, this.humidity));
	}
	
    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;
    }
}

WeatherData

import java.util.ArrayList;
public class WeatherData implements ISubject{
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;
	
	public WeatherData()
	{
		observers = new ArrayList();
	}
	public void registerObserver(IObserver o)
	{
		observers.add(o);
	}
	public void removeObserver(IObserver o)
	{
		int i = observers.indexOf(o);
		if(i >= 0)
			observers.remove(i);
	}
	public void notifyObservers()
	{
		for(int i = 0; i < observers.size(); i++)
		{
			IObserver observer = (IObserver)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();
	}
}

 

WeatherStation

public class WeatherStation {
	public static void main(String[] args)
	{
		WeatherData weatherData = new WeatherData();
		CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
		HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
		//StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
		weatherData.setMeasurements(80, 65, 30.4f);
		System.out.println("------------------------");
		weatherData.setMeasurements(82, 70, 29.2f);
		System.out.println("------------------------");
		weatherData.setMeasurements(78, 90, 29.2f);
	}
}

Output:

Current conditions: 80.0F degrees and 65.0% humidity
Heat index is 82.95535
------------------------
Current conditions: 82.0F degrees and 70.0% humidity
Heat index is 86.90124
------------------------
Current conditions: 78.0F degrees and 90.0% humidity
Heat index is 83.64967