观察者模式

7/9/2021

# 设计原则

  • 为了对象之间的松耦合而努力
  • 动静分离:观察者的具体实现和数量可能变化,从主题中独立出来,可以改变依赖于主题的对象,却不必改变主题
  • 针对接口:观察者是一个超类型,观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。
  • 多用组合:观察者组合成了观察者列表,观察者和主题间没有继承关系,对象之间的关系是在运行时利用主题的方式产生的

# 什么是观察者模式

观察者模式定义了对象之间的 一对多依赖,当一个对象改变状态时,他的所有依赖者都会收到通知并自动更新

  • 这样,对于所有需要知晓数据的观察者,他们不再需要直接控制同一份数据,可以得到更干净的 OO 设计。
  • 观察者模式提供了一种对象设计,让主题和观察者之间松耦合。
    • 主题不需要知道观察者的具体类是谁
    • 任何时候都可以增加新的观察者
    • 新类型的观察者不需要修改主题的代码
    • 可以独立复用主题或观察者
  • 主题使用观察者提供的统一接口来调用每一个不同的观察者
  • 使用观察者模式时,可以推或者拉数据,推的方法可能更为正确
  • 多个观察者之间的通知次序较难保证

# 观察者模式的实现

  1. 主题接口(Subject):

    public interface Subject {
        public void registerObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyObservers();
    }
    
    1
    2
    3
    4
    5
  2. 观察者接口(Observer):

    public interface Observer {
        public void update(Data d);
    }
    
    1
    2
    3
  3. 主题实现:

    public class WeatherData implements Subject {
        private ArrayList observers;
        public WeatherData () {
            observers = new ArrayList();
        }
    
        public void registerObserver(Observer o) {
            observers.add(o);
        }
    
        public void notifyObservers(Observer o) {
            for (int i = 0; i < observers.size(); i++>) {
                Observer observer = (Observer)observers.get(i);
                observer.update();
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  4. 观察者实现:

    public class Client implements Observer, OtherAPIInterface {
        private Subject subject;
    
        public Client(Subject subject) {
            this.subject = subject;
            subject.registerObserver(this);
        }
    
        public void update() {
            ...
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    • 与策略模式相比,观察者是在初始化时主动调用主题的 registerObserver 方法完成注册,是在订阅者的构造函数中完成
    • 观察者需要保存对 Subject 的引用。

# java 内置观察者模式

java.util 包中有最基本的 Observer 接口和 Observable 类,可以定义自己的类,扩展 observable,观察者需要实现 Observer 接口。

  1. 对象变成观察者:实现 update(Observable o, Object arg) 方法
  2. 观察者送出通知:调用 setChanged() 方法,然后调用 notifyObservers()notifyObservers(Object arg) 中的任一个。
Last Updated: 7/10/2021, 12:33:34 AM