观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新。
关于观察者,主题只需要知道观察者实现了某个接口。主题不需要知道观察者的具体类是谁,做了什么或者其他的什么细节,任何时候都可以添加新的观察者或者删除观察者。下面就以一个例子来实现观察者模式。
首先新建一个主题、观察者以及显示的接口
public interface Subject {
public void registerObserver(Observe observe);
public void removeObserver(Observe observe);
public void notifyObserver();
}
public interface Observe {
public void update(float temp,float humidity,float pressure);
}
public interface DisplayElement {
public void display();
}
然后通过实现上述的接口实现一个数据源
public class WeatherData implements Subject {
private ArrayList<Observe> observes;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observes = new ArrayList<Observe>();
}
@Override
public void registerObserver(Observe observe) {
observes.add(observe);
}
@Override
public void removeObserver(Observe observe) {
if(observes.contains(observe)){
observes.remove(observe);
}
}
@Override
public void notifyObserver() {
for (int i = 0; i < observes.size(); i++) {
Observe observe = observes.get(i);
observe.update(temperature, humidity, pressure);
}
}
public void measurementChanged(){
notifyObserver();
}
public void setMeasurements(float temperature, float humidity, float pressure){
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
}
数据源完成时候就是要展示数据,也就是实现观察者
public class CurrentConditionsDisplay implements Observe, DisplayElement {
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("当前气温::"+temperature+"摄氏度,相对湿度为:"+humidity+"%");
}
@Override
public void update(float temp, float humidity, float pressure) {
this.humidity = humidity;
this.temperature = temp;
display();
}
}
public class ForecastDisplay implements Observe,DisplayElement{
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;
public ForecastDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("天气不错,可以出去郊游!");
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
public class StatisticsDisplay implements Observe,DisplayElement{
private float temperature;
private WeatherData weatherData;
private List<Float> list;
public StatisticsDisplay(WeatherData weatherData) {
list = new ArrayList<Float>();
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
// 排序
Collections.sort(list);
float temp = 0;
for (int i = 0; i < list.size(); i++) {
temp+=list.get(i);
}
int vagtemp = (int) (temp/list.size());
System.out.println("气温最大值/平均值/最小值:"+list.get(list.size()-1)+"/"+vagtemp+"/"+list.get(0)+" 摄氏度");
}
@Override
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
list.add(temp);
display();
}
}
上述三个观察者都是跟着weatherData获取数据
测试程序:
“`
public class WeatherTest {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay display = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
weatherData.setMeasurements(20, 75, 30.4f);
weatherData.setMeasurements(32, 70, 29.4f);
weatherData.setMeasurements(18, 90, 31.4f);
}
}
“`