观察者模式,定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
1. 定义主题
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
2. 定义观察者
public interface Observer {
void update(float temperature, float humidity, float pressure);
}
3. 实现主题
public class WeatherData implements Subject {
private float temperature;
private float humidity;
private float pressure;
private List<Observer> observers;
public WeatherData() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
if (null == observer) {
return;
}
if (!observers.contains(observer)) {
observers.add(observer);
}
}
@Override
public void removeObserver(Observer observer) {
if (observers.indexOf(observer) != -1) {
observers.remove(observer);
}
}
@Override
public void notifyObserver() {
observers.forEach(observer -> {
observer.update(temperature, humidity, pressure);
});
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();
}
private void measurementsChanged() {
notifyObserver();
}
}
4. 实现观察者
public interface DisplayElement {
void display();
}
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 display() {
System.out.println("Current conditions: " + temperature + "F degree and " + humidity + "% humidity");
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}
5. JDK自带观察者方式实现
import java.util.Observable;
import java.util.Observer;
public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure =pressure;
measurementsChanged();
}
private void measurementsChanged() {
setChanged();
notifyObservers();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
}
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private Observable observable;
private float temperature;
private float humidity;
public CurrentConditionsDisplay(Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable observable, Object arg) {
if (observable instanceof WeatherData) {
WeatherData weatherData = (WeatherData) observable;
// 观察者主动的拉取想要的消息
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
display();
}
}
@Override
public void display() {
System.out.println("Current conditions: " + temperature + "F degree and " + humidity + "% humidity");
}
}
体现设计原则:为了交互对象之间的松耦合设计而努力
虽然jdk也自带了Observer与Observable,但不建议使用,其违反了多用组合,少用继承设计规则。 从该气象站实例中,得不到正确的通知结果(JDK自带倒叙输出),并且当某一观察者update异常时,未正确捕获将导致其他通知失败,而自定义可以在notifyObserver()中统一捕获处理