【Design Pattern】Behavioural - Observer

Posted by 西维蜀黍 on 2018-11-11, Last Modified on 2022-12-10

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