参考 Head First设计模式
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
观察者模式的使用场景
比如swing中JButton可以有很多个Listener。
在数据报警中,可以给报警源注册邮件,钉钉,微信,短信等通知方式。
观察者模式类图

Java内置观察者模式的弊端
可观察者是一个“类”而不是一个“接口”,更糟的是,它甚至没有实现一个接口。这就违反了设计原则:“面向接口编程,而不是面向类编程”。不幸的是,java.util.Observable的实现有许多问题,限制了它的使用和复用。
如果你看看Observable API,你会发现setChanged()方法被保护起来了(被定义成 protected)。那又怎么样呢?这意味着:除非你继承自Observable,否则你无法创建Observable实例并组合到你自己的对象中来。这个设计违反了第二个设计原则:“多用组合,少用继承”。
观察者模式具体实现
1 2 3 4 5 6 7
   | package com.hohode.model.oberver;
  public interface Subject {     public void registerObserver(Observer o);     public void removeObserver(Observer o);     public void notifyObservers(); }
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | package com.hohode.model.oberver;
  import java.util.ArrayList;
 
  public class WeatherData implements Subject{     private ArrayList observers;     private float temperature;     private float humidity;     private float pressure;     public WeatherData() {         observers = new ArrayList<>();     }     public void registerObserver(Observer o) {         observers.add(o);     }     public void removeObserver(Observer o) { int i = observers.indexOf(o);         if (i >= 0) {             observers.remove(i);         }     }     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();     }
  }
   | 
 
1 2 3 4 5
   | package com.hohode.model.oberver;
  public interface Observer {     public void update(float temp,float humidity,float pressure); }
   | 
 
1 2 3 4 5
   | package com.hohode.model.oberver;
  public interface DisplayElement {     public void display(); }
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | package com.hohode.model.oberver;
  public class CurrentConditionsDisplay implements Observer, DisplayElement {     private float temperature;     private float humidity;     private Subject weatherData;     public CurrentConditionsDisplay(Subject weatherData) {         this.weatherData = weatherData;         weatherData.registerObserver(this);     }     public void update(float temperature, float humidity, float pressure) { this.temperature = temperature;         this.humidity = humidity;         display();     }     public void display() {         System.out.println("Current conditions: " + temperature+ "F degrees and " + humidity + "% humidity");
      } }
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13
   | package com.hohode.model.oberver;
  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);     } }
   |