All Courses
OOP: DESIGN PATTERNS

Observer Pattern

Concept Definition

Observer models a one-to-many notification relationship. One object, called the subject, stores a list of observers. When the subject changes, it notifies every observer through a common interface.

Think of a university notice board. The department posts one update, and many students react to the same announcement.

Why It Matters

Observer helps when several objects need to react to the same event without the subject knowing each concrete class. A subject such as PriceFeed, Button, or GameScore can notify displays, loggers, and alerts through the same Observer interface. This reduces direct coupling between the object that changes and the objects that respond.

In C++, Observer also teaches lifetime awareness because observers are often non-owning references or pointers.

Syntax Block

class Observer {
public:
    virtual ~Observer() = default;      // safe base cleanup
    virtual void update(int value) = 0; // notification contract
};

class Subject {
    std::vector<Observer*> observers;   // non-owning observer list
};

Explained Code

Example: Price Observer

#include <iostream> // std::cout
#include <vector>   // std::vector

class Observer {
public:
    virtual ~Observer() = default;                // safe polymorphic base
    virtual void update(int price) = 0;           // notification method
};

class ConsoleAlert : public Observer {
public:
    void update(int price) override {             // handle new value
        std::cout << "New price: " << price << '\n'; // display update
    }
};

class PriceFeed {
private:
    std::vector<Observer*> observers;             // non-owning pointers

public:
    void addObserver(Observer& observer) { observers.push_back(&observer); } // subscribe

    void setPrice(int price) {
        for (Observer* observer : observers) {    // notify each observer
            observer->update(price);              // polymorphic callback
        }
    }
};

PriceFeed does not know whether an observer prints, saves, emails, or updates a UI. It only calls update().

Key Points / Rules

  • Use Observer when one changing object has many dependents.
  • Keep the subject dependent on the observer interface, not concrete observers.
  • Decide clearly whether the subject owns observers or only references them.
  • Provide unsubscribe logic in larger systems.
  • Avoid doing slow work inside notifications if it blocks the subject.

Common Mistakes

  1. Dangling observer pointers. If an observer is destroyed but the subject still stores its address, the next notification is unsafe.
  2. Letting observers modify the subject during notification without care. This can invalidate lists or create confusing update loops.
  3. Making the subject know every observer type. That defeats the loose coupling of the pattern.
  4. Using Observer when one direct function call is enough. The pattern is for one-to-many change notification.

Quick Check

  1. Why does PriceFeed store Observer* instead of ConsoleAlert objects?
  2. What lifetime problem can happen in a C++ Observer implementation?

Viva Answer

Observer is a pattern where a subject notifies many observers when its state changes. It reduces coupling, but C++ implementations must handle observer lifetime carefully.