观察者模式

观察者模式:
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 设计原则:
为了交互对象之间的松耦合设计而努力。 主题和观察者定义了一对多的关系,参见报纸订阅服务,报社是主题,用户是观察者们。
出版方+订阅者=观察者模式:
1、当报社出版新的报纸时,会推送给用户。只要是报社的订户,就会一直收到新报纸。
2、取消报纸订阅服务,就不会收到新报纸。
3、只要报社还在运营,就会一直有人向报社订阅报纸或取消订阅。 主题向观察者推送消息,有两种推送消息的方式,“推”和“拉”。 实例:建立一个气象观测站,WeatherData对象知道如何从气象站获取最新数据,随即显示在布告板上。
以下是“推”的方式:主题推送数据给观察者。
Java由内置的观察者模式API,但以下用自定义的观察者模式来实现“推”方式: package mypackage; public interface Subject {   //主题接口
  public void registerObserver(Observer o);//注册观察者
  public void removeObserver(Observer o);//移除观察者
  public void notifyObservers();  //通知更新
} package mypackage; public interface Observer {   //观察者接口
  public void update(float temp,float humidity,float pressure);
} package mypackage; public interface DisplayElement {  //布告板接口
  public void display();
} package mypackage; import java.util.ArrayList; public class WeatherData implements Subject { //具体的主题 WeatherData
 private ArrayList observers;
 private float temperature;
 private float humidity;
 private float pressure;
 public WeatherData() {
  observers=new ArrayList();
 }
 @Override
 public void registerObserver(Observer o) {
  observers.add(o);  }  @Override
 public void removeObserver(Observer o) {
  int i = observers.indexOf(o);
  if(i>0) {
   observers.remove(i);
  }  }  @Override
 public void notifyObservers() {
  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();
 } } package mypackage; public class CurrentConditionDisplay implements Observer, DisplayElement {//具体的观察者,一个对象就是一个观察者
 private float temperature;
 private float humidity;
 private Subject weatherData;
 
 
 
 public CurrentConditionDisplay(Subject weatherData) {
  this.weatherData=weatherData;
  weatherData.registerObserver(this);
 }  @Override
 public void display() {
  System.out.println("Current conditions:"+temperature+"F degrees and"+humidity+"%humidity");  }  @Override
 public void update(float temperature, float humidity, float pressure) {//获取更新数据
  this.temperature=temperature;
  this.humidity=humidity;
  display();  }   } package mypackage; public class WeatherStation {  public static void main(String[] args) {
  WeatherData weatherData = new WeatherData();
  
  CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay(weatherData);//创建一个观察者实例
  weatherData.setMeasurements(80, 65, 30.4f);//赋值气象数据
  weatherData.setMeasurements(82, 70, 29.2f);
  weatherData.setMeasurements(78, 90, 29.2f);  } } 以下是“拉”的方式:
利用Java内置API实现:
package mypackage; public interface DisplayElement { //自定义的布告板接口
  public void display();
} package mypackage; import java.util.Observable;//Java内置的主题类 public class WeatherData extends Observable{
 private float temperature;
 private float humidity;
 private float pressure;
 
 public WeatherData() {}
 
 public void measurementsChangerd() {
  setChanged(); //需要,把changed标志设置为true,notifyObservers()才会通知观察者
  notifyObservers();
 }
 
 public void setMeasurements(float temperature,float humidity,float pressure) {
  this.temperature=temperature;
  this.humidity=humidity;
  this.pressure=pressure;
  measurementsChangerd();
 }  public float getTemperature() {
  return temperature;
 }  public float getHumidity() {
  return humidity;
 }  public float getPressure() {
  return pressure;
 }
 
 
}
package mypackage; import java.util.Observable;
import java.util.Observer; //Java内置的观察者接口 public class CurrentConditionsDisplay implements Observer, DisplayElement{
 Observable observable;
 private float temperature;
 private float humidity;
 
 public CurrentConditionsDisplay(Observable observable) {
  this.observable=observable;
  observable.addObserver(this);
 }
 
 @Override
 public void display() {
  System.out.println("Current conditions:"+temperature+"F degrees and"+humidity+"%humidity");
  
 }
 
 @Override
 public void update(Observable o, Object arg) {
  if(o instanceof WeatherData) {  
   WeatherData weatherData = (WeatherData)o;
   this.temperature=weatherData.getTemperature(); //“拉”数据
   this.humidity=weatherData.getHumidity();
   display();
  }
  
 } } package mypackage; public class WeatherStation {  public static void main(String[] args) {
  WeatherData weatherData = new WeatherData();
  
  CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherData);
  weatherData.setMeasurements(80, 65, 30.4f);
  weatherData.setMeasurements(82, 70, 29.2f);
  weatherData.setMeasurements(78, 90, 29.2f);  } } Java内置的Observable是一个类,类是单继承的,限制了复用潜力。没有Observable接口也无法建立自己的实现
和Java内置的ObserverAPI搭配使用也无法换成另一套实现,比如setChanged()是受保护的,除非继承,
否则无法创建Observable实例并组合到自己的对象中。
上一篇:《Head First 设计模式》读书笔记——观察者模式


下一篇:headFirst设计模式——观察者模式