观察者模式

观察者模式:
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的全部依赖者都会收到通知并自动更新。
设计原则:
为了交互对象之间的松耦合设计而努力。
主题和观察者定义了一对多的关系,参见报纸订阅服务,报社是主题,用户是观察者们。
出版方+订阅者=观察者模式:
一、当报社出版新的报纸时,会推送给用户。只要是报社的订户,就会一直收到新报纸。
二、取消报纸订阅服务,就不会收到新报纸。
三、只要报社还在运营,就会一直有人向报社订阅报纸或取消订阅。
主题向观察者推送消息,有两种推送消息的方式,“推”和“拉”。
实例:创建一个气象观测站,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实例并组合到本身的对象中。
相关文章
相关标签/搜索