觀察者模式: 定義一系列對象之間的一對多關系;當一個對象改變狀態,它的依賴都會被通知。 主要由主題(Subject)和觀察者(Observer)組成。
代碼實現
package com.designpatterns.observer;/*** 定義主題接口*/
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}
/*** 定義觀察者接口*/
public interface Observer {public void update(float temp,float humidity,float pressure);//當主題狀態變更時,被調用
}
package com.designpatterns.observer;/*** 定義天氣情況顯示的元素接口*/
public interface DisplayElement {public void display();
}
package com.designpatterns.observer;import java.util.ArrayList;
import java.util.List;/*** 具體主題的實現*/
public class WeatherDataConcretSubject implements Subject{private List<Observer> observers;private float temperature;private float humidity;private float pressure;public WeatherDataConcretSubject(){observers=new ArrayList<>();}@Overridepublic void registerObserver(Observer o) {observers.add(o);}@Overridepublic void removeObserver(Observer o) {observers.remove(o);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(temperature,humidity,pressure); //觀察者更新天氣數據}}public void measurementsChanged(){notifyObservers();//當測量到新的天氣數據,通知觀察者}/*** 設置天氣測試數據* @param temperature* @param humidity* @param pressure*/public void setMeasurements(float temperature,float humidity,float pressure){this.temperature=temperature;this.humidity=humidity;this.pressure=pressure;measurementsChanged();}}
package com.designpatterns.observer;/**** 具體每個觀察者實現。每個觀察著注冊具體主題以接口更新*** 顯示當前的天氣情況***/
public class CurrentConditionsDisplay implements Observer, DisplayElement{private float temperature;private float humidity;private WeatherDataConcretSubject weatherDataConcretSubject;public CurrentConditionsDisplay(WeatherDataConcretSubject weatherDataConcretSubject){this.weatherDataConcretSubject=weatherDataConcretSubject;weatherDataConcretSubject.registerObserver(this);}@Overridepublic void update(float temp, float humidity, float pressure) {this.temperature=temp;this.humidity=humidity;display();}@Overridepublic void display() {System.out.println("Current conditions:"+temperature+"F degrees and "+ humidity+"% humidity ");}
}
package com.designpatterns.observer;public class ForecastDisplay implements Observer,DisplayElement{private float temperature;private float humidity;private WeatherDataConcretSubject weatherDataConcretSubject;public ForecastDisplay(WeatherDataConcretSubject weatherDataConcretSubject){this.weatherDataConcretSubject=weatherDataConcretSubject;weatherDataConcretSubject.registerObserver(this);}@Overridepublic void display() {//顯示預報的天氣System.out.println("ForecastDisplay:"+temperature+"F degrees and "+ humidity+"% humidity ");}@Overridepublic void update(float temp, float humidity, float pressure) {this.temperature=temp;this.humidity=humidity;display();}
}
package com.designpatterns.observer;public class StatisticsDisplay implements Observer,DisplayElement{private float temperature;private float humidity;private WeatherDataConcretSubject weatherDataConcretSubject;public StatisticsDisplay(WeatherDataConcretSubject weatherDataConcretSubject){this.weatherDataConcretSubject=weatherDataConcretSubject;weatherDataConcretSubject.registerObserver(this);}@Overridepublic void update(float temp, float humidity, float pressure) {this.temperature=temp;this.humidity=humidity;display();}@Overridepublic void display() {//顯示測量的avg,min,max值System.out.println("StatisticsDisplay:"+temperature+"F degrees and "+ humidity+"% humidity ");}
}
package com.designpatterns.observer;/*** 觀察者模式測試*/
public class WeatherStationTest {public static void main(String[] args) {WeatherDataConcretSubject weatherDataConcretSubject=new WeatherDataConcretSubject();CurrentConditionsDisplay currentConditionsDisplay=new CurrentConditionsDisplay(weatherDataConcretSubject);StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherDataConcretSubject);ForecastDisplay forecastDisplay=new ForecastDisplay(weatherDataConcretSubject);//設置模擬的氣象數據weatherDataConcretSubject.setMeasurements(80,65,30.4f);weatherDataConcretSubject.setMeasurements(82,70,29.2f);weatherDataConcretSubject.setMeasurements(78,90,29.2f);}
}