Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsBehavioral Design Patterns
✓ FreeBeginner· 6 min read

Observer Pattern

The subject-notifies-observers pattern behind most event systems — push vs pull models, and the classic memory leak from un-removed observers.

Published September 23, 2026


Observer Pattern

The idea: one-to-many state-change notification

A subject maintains a list of observers and notifies all of them when its state changes — neither side needs to know the other's concrete type, only the shared Observer contract.

interface StockObserver { void onPriceChange(String symbol, double newPrice); }

class StockPriceTracker { // the subject
    private final List<StockObserver> observers = new ArrayList<>();
    private double price;

    void subscribe(StockObserver o) { observers.add(o); }
    void unsubscribe(StockObserver o) { observers.remove(o); }

    void updatePrice(String symbol, double newPrice) {
        this.price = newPrice;
        for (StockObserver o : observers) o.onPriceChange(symbol, newPrice); // notify everyone
    }
}

class DisplayPanel implements StockObserver {
    public void onPriceChange(String symbol, double price) { System.out.println(symbol + ": " + price); }
}
class PriceAlertService implements StockObserver {
    public void onPriceChange(String symbol, double price) { if (price > 100) triggerAlert(symbol); }
    private void triggerAlert(String symbol) { /* ... */ }
}
StockPriceTracker tracker = new StockPriceTracker();
tracker.subscribe(new DisplayPanel());
tracker.subscribe(new PriceAlertService());
tracker.updatePrice("AAPL", 150.0); // both subscribers react independently

Neither DisplayPanel nor PriceAlertService know about each other, and StockPriceTracker doesn't know what its observers actually do with the notification — it just broadcasts. This is the foundation almost every event/pub-sub system builds on, from GUI listeners to message queues.

Push vs pull models

The example above is push: the subject sends the full new state (symbol, newPrice) directly in the notification. The alternative is pull: the subject only sends a minimal "something changed" signal, and the observer calls back into the subject to fetch whatever specific data it needs.

interface PullObserver { void onUpdate(StockPriceTracker subject); } // subject reference, not data

class DisplayPanel implements PullObserver {
    public void onUpdate(StockPriceTracker subject) {
        double price = subject.getCurrentPrice(); // observer decides what it needs, and pulls it
    }
}

Push is simpler and cheaper when every observer wants roughly the same data. Pull is more flexible when different observers care about different subsets of state, avoiding the subject having to know every possible thing an observer might want.

The classic Observer leak: un-removed observers

class ExpensiveService {
    ExpensiveService(StockPriceTracker tracker) {
        tracker.subscribe(this::onPriceChange); // subscribed, but never unsubscribed
    }
    private void onPriceChange(String s, double p) { /* ... */ }
}

If ExpensiveService instances are meant to be short-lived but the StockPriceTracker is long-lived, every ExpensiveService that never calls unsubscribe() stays referenced forever by the tracker's observer list — the garbage collector can't reclaim it, since the tracker still holds a live reference. This is a textbook listener/callback leak (also called out in Memory Leaks in Java): the fix is either explicit unsubscription in a lifecycle hook (close(), @PreDestroy), or using weak references for the observer list so the GC can collect observers that nothing else holds onto.

Follow-up questions this topic invites — and their answers

Q: Is Java's own PropertyChangeListener an Observer implementation? A: Yes — java.beans.PropertyChangeSupport is essentially a built-in Observer subject, and Swing/AWT's event listener model (ActionListener, etc.) follows the same shape throughout the JDK.

Q: How does Observer relate to a message queue / event bus in a backend system? A: Same core idea at a different scale and with different delivery guarantees — a message queue decouples publisher and subscriber across processes/services (with persistence, retry, and ordering concerns Observer doesn't address in-process), but the fundamental "notify interested parties without either side knowing the other's concrete type" relationship is identical.

Q: What happens if an observer's callback throws an exception during notification? A: In the naive loop shown above, an exception in one observer's onPriceChange would propagate up and prevent any later observers in the list from being notified at all — production Observer implementations typically wrap each observer call in its own try/catch so one misbehaving observer can't break notification for the rest.

Q: Would you use push or pull for a UI that shows a live dashboard of many different metrics? A: Pull tends to fit better there — different dashboard widgets likely care about different subsets of the subject's state, and pushing every possible field to every observer regardless of relevance wastes both bandwidth and each observer's effort filtering out data it doesn't need.

Previous

Strategy Pattern

Next

Command Pattern

AI Tutor

Lesson: Observer Pattern

Quick actions

AI responses can be inaccurate. Verify critical information.