JDK内置的观察者模式
- 观察者,根据不同的主题的更新来决定自己是否更新,不能在改变主题的状态了, 否则会死循环。
- 具体的观察者绑定了某一个主题
- 观察者不能改变主题的状态,否则会陷入死循环。
- 被观察者,首先设置改变,其次通知所有的观察者。
- 增删都加上锁
- 调用的时候,复制一份,让线程私有之后,再慢慢进行调用。
改变之后,使用下面的代码进行通知所有的观察者。
setChange();
notifyAllObservers();
Observable代码详解
1. 私有的属性: 是否改变,使用vector进行存储对象。
private boolean changed = false;
private Vector<Observer> obs;
2. 增加对象,是一个带锁的实现
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}
3. 删除对象,同样是一个带锁的实现
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
4. 使用对象是经典,解释了为什么需要设置一个change。 -- 为了提醒用户是否真的需要进行。
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
使用
package observer.v6;
import java.util.Observable;
import java.util.Observer;
public class CurrentWeatherDisplay implements Observer {
Observable observable;
private float temperature;
private float humidity;
private float pressure;
public CurrentWeatherDisplay (Observable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
Observable o2 = new WeatherData();
if (o instanceof WeatherData) {
WeatherData weatherData = (WeatherData)o;
this.temperature = weatherData.getTemperature();
this.humidity = weatherData.getHumidity();
this.pressure = weatherData.getPressure();
display();
}
}
public void display() {
System.out.println("温度:" + this.temperature +
" 湿度: " + humidity + " 压力:" + this.pressure);
}
}
package observer.v6;
import java.util.List;
import java.util.Observable;
public class WeatherData extends Observable {
private float temperature;
private float humidity;
private float pressure;
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
public float getTemperature() {
return temperature;
}
public void setTemperature(float temperature) {
this.temperature = temperature;
}
public WeatherData() {}
public void measurementsChanged() {
setChanged();
notifyObservers();
}
public void setMeasurements(float t, float h, float p) {
this.humidity = h;
this.temperature = t;
this.pressure = p;
measurementsChanged();
}
}
package observer.v6;
public class Main {
public static void main(String[] args) {
WeatherData w = new WeatherData();
w.addObserver(new CurrentWeatherDisplay(w));
w.setMeasurements(1,3,4);
}
}