Observer

Lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.

classDiagram
    class Subject {
        <<interface>>
        +attach(Observer)
        +detach(Observer)
        +notify()
    }
    class ConcreteSubject {
        -Observer[] observers
        -state
        +attach(Observer)
        +detach(Observer)
        +notify()
        +getState()
        +setState()
    }
    class Observer {
        <<interface>>
        +update(Subject)
    }
    class ConcreteObserverA {
        +update(Subject)
    }
    class ConcreteObserverB {
        +update(Subject)
    }

    Subject <|.. ConcreteSubject
    Observer <|.. ConcreteObserverA
    Observer <|.. ConcreteObserverB
    ConcreteSubject o-- Observer
    ConcreteObserverA --> ConcreteSubject
    ConcreteObserverB --> ConcreteSubject

When to use

Use the Observer pattern when changes to the state of one object may require changing other objects, and the actual set of objects is unknown beforehand or changes dynamically.

Explanation

Problem

Imagine that you have two types of objects: a Customer and a Store. The customer is very interested in a particular brand of product (say, it’s a new model of the iPhone) which should become available in the store very soon.

The customer could visit the store every day and check product availability. But while the product is still en route, most of these trips would be pointless.

On the other hand, the store could send tons of emails (which might be considered spam) to all customers each time a new product becomes available. This would save some customers from endless trips to the store. At the same time, it’d upset other customers who aren’t interested in new products.

Solution

The object that has some interesting state is often called subject, but since it’s also going to notify other objects about the changes to its state, we’ll call it publisher. All other objects that want to track changes to the publisher’s state are called subscribers.

The Observer pattern suggests that you add a subscription mechanism to the publisher class so individual objects can subscribe to or unsubscribe from a stream of events coming from that publisher.

Real world problem

  1. Magazines/Newspapers: You subscribe, they deliver.
  2. UI Events: Adding event listeners to DOM elements (button.addEventListener('click', fn)).
  3. Chat Rooms: Users subscribe to a room to receive messages.

Pros and Cons

Pros Cons
- Open/Closed Principle: You can introduce new subscriber classes without having to change the publisher’s code (and vice versa if there’s a publisher interface).
- Runtime Relations: You can establish relations between objects at runtime.
- Random Order: Subscribers are notified in random order.

Comparison

  • Chain of Responsibility: Chain passes a request until some object handles it. Observer notifies all attached objects.
  • Mediator: Mediator encapsulates communication. Observer allows dispersed communication through subscriptions.
  • Singleton: The Observer pattern is often used to implement a centralized event manager (Singleton).

Code example

Typescript

Php