> ## Documentation Index
> Fetch the complete documentation index at: https://akshanshgusain.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Observer Pattern

> Behavioral Patterns

## Definition

**“Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all of its
dependents are notified and updated automatically”**

## Explanation

One object (Subject) maintains a list of observers and sends updates to them when its state changes. Observers implement
a common interface and register with the subject. When the subject’s state updates (e.g. data model change), it calls
`notifyObservers()`, causing each observer’s update method to run. This decouples subjects and observers.

## Code

In this Python example, `ConcreteSubject` maintains a list of observers. Whenever its internal state changes
(some\_business\_logic), it calls `notify()`, which in turn calls `update()` on each attached observer (`ConcreteObserverA`,
`ConcreteObserverB`).

```python theme={null}
from abc import ABC, abstractmethod
from random import randrange
from typing import List

class Subject(ABC):
    @abstractmethod
    def attach(self, observer: "Observer") -> None:
        pass
    @abstractmethod
    def detach(self, observer: "Observer") -> None:
        pass
    @abstractmethod
    def notify(self) -> None:
        pass

class ConcreteSubject(Subject):
    _state: int = None
    _observers: List["Observer"] = []

    def attach(self, observer: "Observer") -> None:
        print("Subject: Attached an observer.")
        self._observers.append(observer)
    def detach(self, observer: "Observer") -> None:
        self._observers.remove(observer)
    def notify(self) -> None:
        print("Subject: Notifying observers...")
        for observer in self._observers:
            observer.update(self)
    def some_business_logic(self) -> None:
        print("\nSubject: I'm doing something important.")
        self._state = randrange(0, 10)
        print(f"Subject: My state has just changed to: {self._state}")
        self.notify()

class Observer(ABC):
    @abstractmethod
    def update(self, subject: Subject) -> None:
        pass

class ConcreteObserverA(Observer):
    def update(self, subject: Subject) -> None:
        if subject._state < 3:
            print("ConcreteObserverA: Reacted to the event")

class ConcreteObserverB(Observer):
    def update(self, subject: Subject) -> None:
        if subject._state == 0 or subject._state >= 2:
            print("ConcreteObserverB: Reacted to the event")

def main():
    subject = ConcreteSubject()

    observer_a = ConcreteObserverA()
    subject.attach(observer_a)
    observer_b = ConcreteObserverB()
    subject.attach(observer_b)

    subject.some_business_logic()
    subject.some_business_logic()

    subject.detach(observer_a)
    subject.some_business_logic()

if __name__ == "__main__":
    main()
```

## Analogy

A news agency and subscribers. When breaking news happens (subject state change), the agency automatically pushes the
news to all registered subscriber clients. Or a magazine subscription: one paper, many readers who get the new issue
when released.

## Interview Insights

**Use Case**: Event-driven systems (UI event listeners), data binding (e.g. MVC frameworks), messaging systems (pub/sub
), caching (invalidate caches when data changes). Useful when changes must propagate to many objects (e.g. model–view
synchronization).\
**Advantages**: Promotes loose coupling: subjects don’t need to know concrete observer classes. Makes it easy to add new
observers at runtime. Simplifies broadcast of events\
**Disadvantages**: Can lead to memory leaks if observers aren’t unsubscribed. Notification order is undefined. If many
observers, notifications can slow down updates. Notification errors in one observer could affect others.\
**Common questions**: “How do you prevent or remove observers (memory leak)?”, “How is this pattern implemented in your
language (e.g. event listeners in Java/.NET)?”, “Difference between Observer and Mediator?”, “How to handle threading
(e.g. asynchronous events)?”.\\
