观察者模式理解
观察者模式 Observer
- 观察者模式定义了一个一对多的依赖关系,让多个观察者对象同时监听一个主题对象
- 当这个主题对象改变时,会通知所有的观察者,让他们能够自动的更新自己
观察者模式的组成
- 抽象主题:把所有的对观察者对象的引用保存在一个集合中,抽象主题提供一个接口,可以注册和移除观察者;
- 抽象观察者:为所有的观察者定义一个接口,当主题的数据更新时给登记的观察者提供通知;
- 具体主题:在具体主题内部状态改变时,给所有登记过的观察者发出通知;
- 具体观察者:实现抽象观察者提供的更新接口,以便本身的状态能够及时更新;
为便于理解可以把主题理解为被观察者
观察者模式的应用
抽象观察者
/**
* 观察者
*/
public interface Observer {
void update();
}
抽象主题
/**
* 主题(发布者、被观察者)
*/
public interface Subject {
/**
* 注册观察者
*/
void registerObserver(Observer observer);
/**
* 移除观察者
*/
void removeObserver(Observer observer);
/**
* 通知观察者
*/
void notifyObservers();
}
显示当前天气的公告牌的数据(具体观察者)
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private WeatherData weatherData;
private float temperature;//温度
private float humidity;//湿度
private float pressure;//气压
public CurrentConditionsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
this.weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println("当前温度为:" + this.temperature + "℃");
System.out.println("当前湿度为:" + this.humidity);
System.out.println("当前气压为:" + this.pressure);
}
@Override
public void update() {
this.temperature = this.weatherData.getTemperature();
this.humidity = this.weatherData.getHumidity();
this.pressure = this.weatherData.getPressure();
display();
}
}
用于获取数据的具体主题(被观察者)
public class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;//温度
private float humidity;//湿度
private float pressure;//气压
private List<Float> forecastTemperatures;//未来几天的温度
public WeatherData() {
this.observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer observer) {
this.observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
this.observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity,
float pressure, List<Float> forecastTemperatures) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.forecastTemperatures = forecastTemperatures;
measurementsChanged();
}
public float getTemperature() {
return temperature;
}
public float getHumidity() {
return humidity;
}
public float getPressure() {
return pressure;
}
public List<Float> getForecastTemperatures() {
return forecastTemperatures;
}
}
用于公告牌显示的接口(观察者)
public interface DisplayElement {
void display();
}
公告牌CurrentConditionsDisplay实现了Observer和DisplayElement接口,在他们的构造方法中会调用WeatherData的registerObserver方法将自己注册成观察者,这样被观察者WeatherData就会持有观察者的应用,并将它们保存到一个集合中。当被观察者WeatherData状态发送变化时就会遍历这个集合,循环调用观察者公告牌更新数据的方法。后面如果我们需要增加或者删除公告牌就只需要新增或者删除实现了Observer和DisplayElement接口的公告牌就好了。
- 参考链接:
�������
网友评论