这里写自定义目录标题
基本定义
让你的对象知悉现状
在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动跟新
案例
问题:贵公司需要建立一个气象观测站!该气象观测站必须建立在我们申请的WeatherDate对象上,由WeatherDate对象负责追踪目前的天气状况(温度,湿度,气压)。我们希望建立一个应用,有三种布告板,分别显示目前的状况, 气象统计及简单的预报。当WeatherDate对象获得最新的测量数据时,三种布告板必须实时跟新。
这个是WeatherDate的源文件,主要的功能是实现三个使用的天气数据布告板:“目前状况”布告,“气象统计”布告,“天气预报”布告。此系统是可扩展的,对于布告是可随心的添加和删除
一般做法(错误案例)
public class WeatherData {
//实例变量申明
public void measurementsChanged() {
//调用三个get××方法
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
//跟新布告板
currentConditionsDisplay.update(temp,humidity,pressure);
statisticsDisplay.update(temp,humidity,pressure);
forecastDisplay.update(temp,humidity,pressure);
//这里是其他方法
}
}
原因:
- 针对具体实现编程,不是针对接口
- 对于每个新的布告板我们都必须修改代码
- 我们无法动态的增加和删除布告板
- 我们没有封装改变的部分
观察者模式
1-定义观察者模式:类图
2-优点:观察者模式提供一种对象设计,让主题和观察者之间松耦合
基于观察者模式设计
代码:WeatherData类
public class WeatherData implements Subject{
//我们加上一个ArrayList来记录观察者,此ArrayList是再构造器中建立的
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList();
}
//当注册观察者时,将其加入到集合
public void registerObserver(Observer o) {
observers.add(o);
}
//当取消注册,我们将它从集合中删除即可
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i > 0) {
observers.remove(i);
}
}
//将最新转态通知给每一个观察者
public void notifyObserver() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer)observers.get(i);
observer.update(temperature, humidity,pressure);
}
}
//当气象站得到更新观测值时,我们通知观察者
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
//WeatherData的其他方法
}
目前状况布告板CurrentConditionsDisplay类
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {//构造器需要weather对象(也就是主题)作为注册之用
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
//当温度和湿度保存起来,然后调用display()
public void update(float temperature,float humidity,float pressure) {
this.temperature = temperature;
this.humidity = humidity;
Displayable();
}
public void display() {//显示最近温度和湿度
System.out.println("Current conditions:"+temperature+"F degrees and"+humidity+"%humidity");
}
}
参考 https://blog.csdn.net/L_BestCoder/article/details/66967740