目的

定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。
主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。
观察者1.jpg

类图

主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。
观察者(Observer)的注册功能需要调用主题的 registerObserver()方法。
观察者类图.png

实现

天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。
观察者2.jpg

  1. public interface Subject {
  2. void registerObserver(Observer o);
  3. void removeObserver(Observer o);
  4. void notifyObserver();
  5. }
  6. public class WeatherData implements Subject {
  7. private List<Observer> observers;
  8. private float temperature;
  9. private float humidity;
  10. private float pressure;
  11. public WeatherData() {
  12. observers = new ArrayList<>();
  13. }
  14. public void setMeasurements(float temperature, float humidity, float pressure) {
  15. this.temperature = temperature;
  16. this.humidity = humidity;
  17. this.pressure = pressure;
  18. notifyObserver();
  19. }
  20. @Override
  21. public void registerObserver(Observer o) {
  22. observers.add(o);
  23. }
  24. @Override
  25. public void removeObserver(Observer o) {
  26. int i = observers.indexOf(o);
  27. if (i >= 0) {
  28. observers.remove(i);
  29. }
  30. }
  31. @Override
  32. public void notifyObserver() {
  33. for (Observer o : observers) {
  34. o.update(temperature, humidity, pressure);
  35. }
  36. }
  37. }
  38. public interface Observer {
  39. void update(float temp, float humidity, float pressure);
  40. }
  41. public class StatisticsDisplay implements Observer {
  42. public StatisticsDisplay(Subject weatherData) {
  43. weatherData.reisterObserver(this);
  44. }
  45. @Override
  46. public void update(float temp, float humidity, float pressure) {
  47. System.out.println("StatisticsDisplay.update: " + temp + " " + humidity + " " + pressure);
  48. }
  49. }
  50. public class CurrentConditionsDisplay implements Observer {
  51. public CurrentConditionsDisplay(Subject weatherData) {
  52. weatherData.registerObserver(this);
  53. }
  54. @Override
  55. public void update(float temp, float humidity, float pressure) {
  56. System.out.println("CurrentConditionsDisplay.update: " + temp + " " + humidity + " " + pressure);
  57. }
  58. }
  59. public class WeatherStation {
  60. public static void main(String[] args) {
  61. WeatherData weatherData = new WeatherData();
  62. CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
  63. StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
  64. weatherData.setMeasurements(0, 0, 0);
  65. weatherData.setMeasurements(1, 1, 1);
  66. }
  67. }
  68. 运行结果
  69. CurrentConditionsDisplay.update: 0.0 0.0 0.0
  70. StatisticsDisplay.update: 0.0 0.0 0.0
  71. CurrentConditionsDisplay.update: 1.0 1.0 1.0
  72. StatisticsDisplay.update: 1.0 1.0 1.0

JDK中的体现