观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。观察者模式是一种对象行为型模式。
上述角色可以参考后面的类图。
气象台的改变逻辑会放在measurementsChanged方法中。
public class WeatherData {
public void measurementsChanged() {
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
// 可以理解为更新不同接入气象台网站的显示
currentConditionDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
}
}
以上实现违背了一些设计原则:
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}
public class WeatherData implements Subject{
List<Observer> observerList;
private float temp; //温度
private float humidity; //湿度
private float pressure; //压强
public WeatherData() {
observerList = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observerList.add(o);
}
@Override
public void removeObserver(Observer o) {
observerList.remove(o);
}
@Override
public void notifyObserver() {
observerList.forEach(Observer::update);
}
public void measurementsChanged() {
notifyObserver();
}
public void setMeasurements(float temperatue, float humidity, float pressure) {
this.temp = temperatue;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public float getTemp() {
return temp;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
public interface Observer {
void update();
}
public interface DisplayElement {
public void display();
}
public class CurrentConditionDisplay implements Observer, DisplayElement{
private float temp;
private float humidity;
private float pressure;
private WeatherData weatherData;
public CurrentConditionDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void update() {
this.temp = weatherData.getTemp();
this.humidity = weatherData.getHumidity(); // 观察者需要什么,可以从主题中拉取,是属于拉的模式
this.pressure = weatherData.getPressure();
this.display();
}
@Override
public void display() {
System.out.println("current display:" + temp + " " + humidity + " " + pressure);
}
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentConditionDisplay =
new CurrentConditionDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
}
输出:
current display:80.0 65.0 30.4 // 例子中只定义了一个观察者
spring中的事件驱动模型,具体参考观察者模式