定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
以气象站更新气象信息为例
// 主题接口
public interface SubJect {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
// 气象站实现主题接口
public class WeatherData implements SubJect {
// 气象信息:温度,湿度,气压
private String temperature;
private String humidity;
private String pressure;
// 观察者列表
private List<Observer> observers;
public WeatherData() {
this.observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
if(observers.indexOf(o)>0){
observers.remove(o);
}
}
// 如何通知观察者,其实就是遍历本地的观察者列表,执行它们的update方法
@Override
public void notifyObservers() {
this.temperature = getTemperature();
this.humidity = getHumidity();
this.pressure = getPressure();
for(Observer o: observers){
o.update(temperature,humidity,pressure);
}
}
public String getTemperature() {
return temperature;
}
public String getHumidity() {
return humidity;
}
public String getPressure() {
return pressure;
}
/**
* 气温有变化时立即调用
*/
public void measureChanged(){
notifyObservers();
}
}
// 观察者接口
public interface Observer {
void update(String temperature,String humidity,String pressure);
}
// 这时一个气象统计布告,当气象信息变化时展示
public class 气象统计 implements Observer{
// 本地气象信息
private String temperature;
private String humidity;
private String pressure;
// 主题对象,用来注册自己
private SubJect weatherData;
public 气象统计(SubJect weatherData) {
this.weatherData = weatherData;
// 初始化的时候注册自己
weatherData.registerObserver(this);
}
// 实现update方法,一旦气象信息变化了,主题会调用该方法
@Override
public void update(String temperature, String humidity, String pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
this.display();
}
@Override
public void display() {
System.out.println(toString());
}
@Override
public String toString() {
return "气象统计{" +
"temperature='" + temperature + '\'' +
", humidity='" + humidity + '\'' +
", pressure='" + pressure + '\'' +
'}';
}
}
其实java内置了观察者模式,但是有些内容和上述略有不同,但是都是情理之中。下面一一解释
区别一:
jdk自带的观察者模式中,被观察者接口是Observer
Observer有方法setChanged(),是将一个全局变量变为true,为什么呢?
protected synchronized void setChanged() {
changed = true;
}
显然,当没有变的时候,是不更新的。那么“变”到底指的是什么?其实是对事实的控制,比如说温度,如果精确单位是千分之一,那岂不是温度时时刻刻都在变化,这样更新太频繁了。我们只有当它的温度变化超过一度,才会setChanged(),这时候才会真的通知所有观察者
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);
}
区别二:update方法的参数,理应是Obj对象,而不是自定义的。
update有两个参数,一个是带个Observer的数据,一个是主题本身
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData){
this.temperature = ((WeatherData) o).getTemperature();
this.humidity = ((WeatherData) o).getHumidity();
this.pressure = ((WeatherData) o).getPressure();
display();
}
}
2363

被折叠的 条评论
为什么被折叠?



