【Design Pattern】Behavioural - Observer

Posted by 西维蜀黍 on 2018-11-11, Last Modified on 2025-04-23

1 定义

观察者模式(Observer Pattern)定义了一种一对多的依赖对象关系,使得当那一个对象状态发生改变时,依赖它的多个对象均能得到通知并自动更新(做出相应反应)。

发生状态变化的对象叫观察目标Subject),依赖它的多个对象叫观察者Observers)。subject 通知其 observer 的方式,通常以主动调用 observer 的特定方法进行。

这意味着,在 subject 中存在一个注册列表(Registered list),记录了当自己状态发生变化时,需要调用的每个 observer 对应的特定方法


观察者模式的核心思想,与发布-订阅模式(Publish/Subscribe Pattern)非常类似的,即通过引入一个 ** 事件通知(Event Notification)** 机制将事件两端的对象(事件发生对象和关注该事件发生的对象)实现解耦。

而两者的区别在于:

  • 耦合关系不同

    • 在观察者模式中,Subject 松耦合于 Abstract Observer
    • 而发布 - 订阅模式可以看做是观察者模式的一种变种。通过引入 Broker 层,作为 SubjectObserver 之间的中间层,最终 SubjectObserver 之间不存在任何耦合
  • 讨论的上下文所处的粒度不同

    • 观察者模式往往在一个代码实现的上下文去讨论的(Design Pattern),即 programming language specific;
    • 而发布 - 订阅模式既可以在一个代码实现的上下文去讨论(Design Pattern),也可以从架构设计的角度讨论。这时,发布 - 订阅模式更多是一个架构模式(Architectural Pattern)。比如 ** 面向消息的中间件系统(message-oriented middleware system,MOMS)** 则是从架构层面实现了发布 - 订阅模式的一个典型例子,典型的面向消息的中间件系统包括 JMS(Java Message Service)、ActiveMQ
  • 同异步的实现不同

    • 观察者模式往往以同步的方式实现,即当特定事件发生时,观察者(Observer)的事件处理方法被依次同步调用
    • 发布 - 订阅模式往往以异步的方式实现。当特定事件发生(比如,一个特定的 Topic)时,发布者(Publisher)通知消息队列(Message Queue)或 Broker 对象,此后通知结束。此后,订阅者再去消费这个事件。

2 特点

  • 一个 subject 可以对应多个 observer,这些 observer 之间可以没有任何关系(耦合)。
  • subject 松依赖(松耦合)于 observer,而 observer 不依赖于 subject
  • 同时也可以根据需要随意地向 subject 增加或删除 observer,这意味着系统非常易于扩展。

在应用观察者模式的过程中,通常包括三个行为:

  • 添加(Attach):将一个 observer 添加到 subject 中的注册列表(Registered list)中。这意味着当特定事件发生时,这个 observer 总能收到通知
  • 移除(Detach):将一个已经存在的 observersubject 中的注册列表(Registered list)中移除。这意味着当被移除之后,特定事件发生时,这个 observer 也不会收到通知
  • 通知(Notify):subject 调用 observer 提供的通知更新函数以告知 observer 此时事件发生

3 示例

// TODO

4 优点

  • 观察者模式符合 “开闭原则”(Open/Closed Principle)
  • 观察者模式可用于广播通信
  • 观察者模式在 subjectobserver 之间建立了一个抽象的耦合
  • 使用观察者模式可以实现表现层和逻辑层的分离

5 缺点

  • 如果在 Observersubject 之间有循环依赖时,可能会导致触发无限通知调用,进而导致系统崩溃

6 Note

6.1 Java 的支持

在 JDK 的 java.util 包中,提供了 Observable 类以及 Observer 接口,它们构成了 Java 语言对观察者模式的支持。

6.2 观察者模式在 MVC 中的应用

在常用的 MVC (Model - View - Controller)架构模式中也应用了观察者模式。MVC 中包含三个角色:模型(Model)、视图(View)和控制器(Controller)。

其中 Model 对应于观察者模式中的 subject,而 View 对应于观察者模式中的 observer

当 Model 层中的特定事件发生(如数据发生改变)时,View 层将收到通知(并更新显示的数据),

7 Reference