观察者模式就是:
1、所有的观察者需要被通知,实现了一个接口,供主题调用
2、所有的主题都有一个观察者列表,主题通过调用观察者实现的接口通知观察者。
代码结构(inside代表使用java.util, self使用自定义的接口):
interface DisplayElement:
public interface DisplayElement { public void display(); }
interface subject:
public interface Subject { public void registerObserver(Observer o) ; public void removeObserver(Observer o); public void notifyObserver(); }
interface Observer:
public interface Observer { public void update(float temp, float humidity, float pressure); }
WeatherData
public class WeatherData implements Subject { private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList(); } @Override public void registerObserver(Observer o) { observers.add(o); } @Override public void removeObserver(Observer o) { int i = observers.indexOf(o); if(i >= 0) { observers.remove(i); } } @Override public void notifyObserver() { for (int i = 0; i< observers.size(); i++) { Observer observer = (Observer) observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
CurrentConditionsDisplay
public class CurrentConditionsDisplay implements Observer, DisplayElement { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } @Override public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } @Override public void display() { System.out.println("Current conditions:" + temperature + "F degrees and "+ humidity + "% humidity"); } }
使用jdk内置的观察者接口:
WeatherData
public class WeatherData extends Observable{ private float temperature; private float humidity; private float pressure; public WeatherData() {} public void measurementsChanged() { setChanged(); 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; } }
CurrentConditionsDisplay
public class CurrentConditionsDisplay implements Observer, DisplayElement { Observable observable; private float temperature; private float humidity; public CurrentConditionsDisplay(Observable observable) { this.observable = observable; observable.addObserver(this); } @Override public void update(Observable obs, Object arg) { if(obs instanceof WeatherData){ WeatherData weatherData = (WeatherData) obs; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); display(); } } @Override public void display() { System.out.println("Current conditions:" + temperature + "F degrees and " + humidity + "% humidity"); } }
测试类:
WeatherStationSelf
public class WeatherStationSelf { @Test public void test() { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } }