0%

设计模式之行为型模式(七):观察者模式

1. 观察者模式概述

  • 概述

    • 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
  • Demo

    • 观察者的接口

      1
      2
      3
      public interface Observer {
      void update(String event);
      }
    • 被观察者的父类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      public class Observable {

      private List<Observer> observers = new ArrayList<>();

      public void addObserver(Observer observer) {
      observers.add(observer);
      }

      public void removeObserver(Observer observer) {
      observers.remove(observer);
      }

      public void notifyObservers(String event) {
      for (Observer observer : observers) {
      observer.update(event);
      }
      }
      }
    • 警察属于观察者

      1
      2
      3
      4
      5
      6
      public class PoliceObserver implements Observer {
      @Override
      public void update(String event) {
      System.out.println("警察收到消息,罪犯在" + event);
      }
      }
    • 罪犯属于被观察者

      1
      2
      3
      4
      5
      6
      public class CriminalObservable extends Observable {
      public void crime(String event) {
      System.out.println("罪犯正在" + event);
      notifyObservers(event);
      }
      }
    • 客户端测试

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      public class Client {
      @Test
      public void test() {
      CriminalObservable zhangSan = new CriminalObservable();
      PoliceObserver police1 = new PoliceObserver();
      PoliceObserver police2 = new PoliceObserver();
      PoliceObserver police3 = new PoliceObserver();
      zhangSan.addObserver(police1);
      zhangSan.addObserver(police2);
      zhangSan.addObserver(police3);
      zhangSan.crime("放狗咬人");
      }
      }

2. Java 源码中的观察者模式

  • java.util.Observer 类

    1
    2
    3
    public interface Observer {
    void update(Observable o, Object arg);
    }
    • update() 方法将 Observable 对象也提供给了 Observer
    • update() 方法中的参数类型变成了 Object,保证 Observer 的适用范围更广
  • java.util.Observable 类

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
    obs = new Vector<>();
    }

    public synchronized void addObserver(java.util.Observer o) {
    if (o == null)
    throw new NullPointerException();
    if (!obs.contains(o)) {
    obs.addElement(o);
    }
    }

    public synchronized void deleteObserver(java.util.Observer o) {
    obs.removeElement(o);
    }

    public void notifyObservers() {
    notifyObservers(null);
    }

    public void notifyObservers(Object arg) {
    Object[] arrLocal;
    synchronized (this) {
    if (!hasChanged())
    return;
    arrLocal = obs.toArray();
    clearChanged();
    }
    for (int i = arrLocal.length - 1; i >= 0; i--)
    ((Observer) arrLocal[i]).update(this, arg);
    }

    public synchronized void deleteObservers() {
    obs.removeAllElements();
    }

    protected synchronized void setChanged() {
    changed = true;
    }

    protected synchronized void clearChanged() {
    changed = false;
    }

    public synchronized boolean hasChanged() {
    return changed;
    }

    public synchronized int countObservers() {
    return obs.size();
    }
    }
    • 用于保存观察者列表的容器不是 ArrayList,而是 Vetor
    • 添加了一个 changed 字段,以及 setChanged() 方法和 clearChanged() 方法。分析可知,当 changed 字段为 true 时,才会通知所有观察者,否则不通知观察者。所以当使用此类时,想要触发 notifyObservers() 方法,必须先调用 setChanged() 方法。这个字段相当于在被观察者和观察者之间添加了一个可控制的阀门
    • 提供了 countObservers 方法,用于计算观察者数量
    • 添加了一些 synchronized 关键字保证线程安全

3. 观察者模式练习题(多选)

  • 在电影《让子弹飞》中,马县长、县长夫人和康师爷一起吃着火锅,唱着歌,突然被马匪张麻子给劫了!这个过程中体现了哪些观察者模式?

    1. 马县长观察着火锅
    2. 张麻子观察着县长车队
    3. 县长夫人观察着窗外风景
    4. 康师爷观察着县长夫人

题目解析

马县长观察着火锅,当火锅烫好后吃肉;张麻子观察着县长车队,趁县长车队路过时打劫。3 和 4 都只是凝视,不会因为被观察者的变化而做出任何响应,属于 watch 、不属于 observe

-------------------- 本文结束感谢您的阅读 --------------------