DP-观察者模式代码详解
观察者模式: 定义一系列对象之间的一对多关系;当一个对象改变状态,它的依赖都会被通知。 主要由主题(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);}
}