Skip to content

Observer pattern

一、Observer pattern使用OOP的语言来描述event-driven model

二、observer pattern和 publish-subscribe pattern 比较相关

三、在下面章节中,也对observer pattern进行了说明

1、工程programming-languageMulti-thread&&observer-pattern章节

2、nextptr Using weak_ptr for circular references

四、开源软件中使用observer pattern的

1、spdlog async_logger

wikipedia Observer pattern

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

NOTE: subject对应的是event-driven model的**monitor**的角色,observer对应的是event-driven model的**executor**角色。subject通过调用observer的method来实现message passing。

It is mainly used to implement distributed event handling systems, in "event driven" software. Most modern languages such as C# have built in "event" constructs which implement the observer pattern components.

The observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern.[1] The observer pattern is implemented in numerous programming libraries and systems, including almost all GUItoolkits.

Strong vs. Weak reference

The observer pattern can cause memory leaks, known as the lapsed listener problem, because in basic implementation it requires both explicit registration and explicit deregistration, as in the dispose pattern, because the subject holds strong references to the observers, keeping them alive. This can be prevented by the subject holding weak references to the observers.

NOTE:

一、如何来解决呢?

1、C++,参见:

nextptr Using weak_ptr for circular references

Coupling and typical pub-sub implementations

Typically the observer pattern is implemented with the "subject" (which is being "observed") being part of the object, whose state change is being observed, to be communicated to the observers upon occurrence. This type of implementation is considered "tightly coupled", forcing both the observers and the subject to be aware of each other and have access to their internal parts, creating possible issues of scalability, speed, message recovery and maintenance (also called event or notification loss), the lack of flexibility in conditional dispersion(分散) and possible hindrance(妨碍) to desired security measures.

In some (non-polling) implementations of the publish-subscribe pattern (also called the pub-sub pattern), this is solved by creating a dedicated(专门的) "message queue" server and at times an extra "message handler" object, as added stages between the observer and the observed object whose state is being checked, thus "decoupling" the software components. In these cases, the message queue server is accessed by the observers with the observer pattern, "subscribing to certain messages" knowing only about the expected message (or not, in some cases), but knowing nothing about the message sender itself, and the sender may know nothing about the receivers. Other implementations of the publish-subscribe pattern, which achieve a similar effect of notification and communication to interested parties, do not use the observer pattern altogether.[4][5]

NOTE: 上面这段话对比了MQ和observer pattern。

Still, in early implementations of multi-window operating systems like OS2 and Windows, the terms "publish-subscribe pattern" and "event driven software development" were used as a synonym for the observer pattern.[6]

The observer pattern, as described in the GOF book, is a very basic concept and does not deal with observance removal or with any conditional or complex logic handling to be done by the observed "subject" before or after notifying the observers. The pattern also does not deal with recording the "events", the asynchronous passing of the notifications or guaranteeing they are being received. These concerns are typically dealt with in message queueing systems of which the observer pattern is only a small part.

Related patterns: Publish–subscribe pattern, mediator, singleton.

Example

Python

class Observable(object):
    def __init__(self) -> None:
        self._observers = []

    def register_observer(self, observer) -> None:
        self._observers.append(observer)

    def notify_observers(self, *args, **kwargs) -> None:
        for observer in self._observers:
            observer.notify(self, *args, **kwargs)


class Observer(object):
    def __init__(self, observable) -> None:
        observable.register_observer(self)

    def notify(self, observable, *args, **kwargs) -> None:
        print('Got', args, kwargs, 'From', observable)


subject = Observable()
observer = Observer(subject)
subject.notify_observers('test')

w3sdesign Observer design pattern

Intent

The Observer design pattern solves problems like:

1、How can a one-to-many dependency between objects be defined without making the objects tightly coupled?

2、How can an object notify an open-ended-number of other objects?

NOTE: “open-ended-number of other objects”意味着,在runtime,可以增加observer,也可以删除observer。

The Observer pattern describes how to solve such problems:

1、Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

2、The key idea in this pattern is to establish a flexible notification-registration mechanism that notifies all registered objects automatically when an event of interest occurs.

NOTE: notification-registration mechanism是observer pattern的核心思想,凭借它,observer pattern解决了前面提出的问题。*notification-registration*也叫做publish-subscribe。

NOTE: 在原文的intent节给出的sample class diagram和sample sequence diagram其实就已经展示出了observer design pattern的实现了。

Problem

NOTE: 在原文的这一节给出了一个反例,我们也应该要注意反例。在原文的motivation章节,给出了更加详细的对比。

Implementation

NOTE: 原文的这一节给出的**Push Data**、**Pull Data**实现方式

Sample code

NOTE: 原文给出的sample code非常好。

TODO

observer pattern VS publish subscribe pattern

https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c

microsoft Observer Design Pattern

Events and routed events overview

Handling and raising events

oodesign Observer Pattern

refactoring Observer

NOTE: 前面给出的示例都没有准确描述对不同类型的事件,执行不同的函数,而本文的示例则展示了这一点。它的代码也是值得阅读的https://refactoring.guru/design-patterns

cpppatterns Observer