Skip to content

Observer Pattern: Event-Driven Communication

Tell many objects when something changed

Builds on Interfaces and Coupling and Cohesion

Stage 3core3 min read

Behavioral design patterns are about how objects talk to each other. They keep objects loosely coupled, which means each object depends on the others as little as possible.

Here is the problem. One object changes, and many others need to know. If it calls each one by name, it gets tangled up with all of them.


1. What is the Observer Pattern?

The Observer Pattern is a behavioral design pattern that defines a one-to-many dependency between objects. One object (the subject) holds some data. Many others (the observers) want to know when it changes. The subject tells every observer automatically.

Real-Life Analogy: YouTube Subscriptions

Think of subscribing to a YouTube channel. Once you hit Subscribe and turn on notifications, you do not have to keep checking the channel. When a new video is uploaded, you get a message right away.

  • The Channel: The Subject.
  • The Subscribers: The Observers.
  • The Notification: The automatic message sent when something changes.

2. The Problem: Tight Coupling

In a naive design, the subject has its recipients written into its own code. Adding or removing a subscriber means editing the subject's main logic. This breaks the Single Responsibility Principle (SRP), which says a class should do one job. It also breaks the Open/Closed Principle (OCP), which says code should be open to new features but closed to edits.


3. Class Diagram & Structural Breakdown

The pattern uses interfaces (lists of methods a class must have). The subject only knows Subscriber, not EmailSubscriber or MobileAppSubscriber.

Loading diagram…

YouTubeChannel keeps a list of Subscriber objects and calls update on each. Each subscriber class decides what update does.


4. Pros and Cons

Advantages

  • Loose Coupling: Subjects and observers talk only through a shared interface.
  • Open for Extension: You can add new observer types without editing the subject.
  • Dynamic Subscriptions: Observers can join or leave at runtime.
  • Encourages Reusability: You can reuse one observer class with different subjects.

Disadvantages

  • Unpredictable Sequences: You cannot count on the order in which observers are told.
  • Performance Bottlenecks: Synchronous notifications (the subject waits for each observer in turn) get slow with many observers.
  • Memory Leaks: If you forget to unsubscribe an observer you no longer need, the subject keeps it in memory.
  • Difficult Debugging: The subject never names its observers, so bugs are harder to trace.

5. Use Cases and Limitations

  • State Change Propagation: When a change in one object must show up in many others.
  • Decoupling Core Components: When the publisher should not know who its subscribers are.
  • Dynamic Runtime Modules: Good for UI listeners, plugins and notification modules.

Limitations at Scale

  • Excessive Load: For millions of observers (e.g., a massive celebrity going live), use pub-sub architectures or event queues.
  • Timing Control: If delivery timing must be strict (e.g., financial systems), use message brokers like Kafka or RabbitMQ. A broker is a separate service that delivers messages.

6. Real-World Examples

  1. UI Event Handling: Button clicks or typing listeners in GUI frameworks.
  2. Stock Market Tickers: Updating charts and alerts when a stock price changes.
  3. File System Watchers: IDEs triggering compilers when a file is saved.
  4. Social Media: YouTube or Instagram notifying followers of new posts.

In this topic

Done with this topic?

How well do you know it?