观察者模式:定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它所有依赖者都收到通知并自动更新。
案例:一个WeatherData类可以接受即时温度、湿度等信息,三种不同布告板分别接收信息显示不同内容(以后可能要添加布告板)。解决方案是WeatherData作为主题,布告板作为观察者,接收即时消息。依赖关系很弱,基本只调用其他类的方法,或者不在构造函数调用其他类对象,实现
public interface Subject {
public void registerObserver(Observer o);
public void removerObserver(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update(float temp);
}
public interface DisplayElement {
public void display();
}
public class WeatherData implements Subject {
private ArrayList observers;//在WeatherData声明了Observer的对象->依赖
private float temp;
private float newTemp;
private boolean changed;
@Override
public void registerObserver(Observer o){
observers.add(o);
}
public void removerObserver(Observer o){
int i = observers.indexOf(o);
if (i >= 0) observers.remove(o);
}
public void notifyObservers() {
if (changed){
for (int i = 0;i < observers.size();i++){
Observer observer = (Observer) observers.get(i);//在WeatherData调用了Observer对象的方法->依赖
observer.update(temp);
}
changed = false;
}
}
public void setChanged(){
if (newTemp - temp >= 0.5)//温度变化大于0.5再更新,否则一直更新,很乱
changed = true;
}
}
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temp;
private Subject weatherData;//创建了Subject对象->依赖
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.print(temp);
}
@Override
public void update(float temp) {
this.temp = temp;
display();
}
}
这个大概是书里的代码,没有直接用java.util.Observer等。如果用java内置的模式(不是只靠主题推消息,观察者可以自己拉消息):
public class CurrentConditionsDisplayJavaUtil implements Observer {
private float temp;
Observable observable;
public CurrentConditionsDisplayJavaUtil(Observable obs){
this.observable = obs;
obs.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
if (o instanceof WeatherDataJavaUtil){
WeatherDataJavaUtil weatherDataJavaUtil = (WeatherDataJavaUtil) o;
this.temp = weatherDataJavaUtil.getTemp();
display();
}
}
public void display(){};
}
public class WeatherDataJavaUtil extends Observable {
private float temp;
public WeatherDataJavaUtil(){};
public void measurementsChanged(){
setChanged();
notifyObservers();
}
public float getTemp() {
return temp;
}
}