Observer Pattern
Observer is a behavioral design pattern that lets you define a subscription mechanism to notify multiple objects about any events that happen to the object they’re observing.

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.

Visiting the store vs. sending spam
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.
It looks like we’ve got a conflict. Either the customer wastes time checking product availability or the store wastes resources notifying the wrong customers.
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. Fear not! Everything isn’t as complicated as it sounds. In reality, this mechanism consists of 1) an array field for storing a list of references to subscriber objects and 2) several public methods which allow adding subscribers to and removing them from that list.

A subscription mechanism lets individual objects subscribe to event notifications.
Now, whenever an important event happens to the publisher, it goes over its subscribers and calls the specific notification method on their objects.
Real apps might have dozens of different subscriber classes that are interested in tracking events of the same publisher class. You wouldn’t want to couple the publisher to all of those classes. Besides, you might not even know about some of them beforehand if your publisher class is supposed to be used by other people.
That’s why it’s crucial that all subscribers implement the same interface and that the publisher communicates with them only via that interface. This interface should declare the notification method along with a set of parameters that the publisher can use to pass some contextual data along with the notification.

Publisher notifies subscribers by calling the specific notification method on their objects.
If your app has several different types of publishers and you want to make your subscribers compatible with all of them, you can go even further and make all publishers follow the same interface. This interface would only need to describe a few subscription methods. The interface would allow subscribers to observe publishers’ states without coupling to their concrete classes.
Real-World Analogy
If you subscribe to a newspaper or magazine, you no longer need to go to the store to check if the next issue is available. Instead, the publisher sends new issues directly to your mailbox right after publication or even in advance.
The publisher maintains a list of subscribers and knows which magazines they’re interested in. Subscribers can leave the list at any time when they wish to stop receiving new issues.
Structure
- The Publisher issues events when its state changes. It maintains a subscription infrastructure allowing subscribers to join or leave.
- When an event occurs, the publisher iterates through its subscription list and calls the notification method on each subscriber.
-
The Subscriber interface declares the notification method
(usually
update()). - Concrete Subscribers implement the subscriber interface and react to notifications. The publisher depends only on the interface.
- Publishers may pass contextual data to subscribers during notification, sometimes even passing themselves as arguments.
- The Client creates publisher and subscriber objects and registers subscribers to receive updates.
C++ Implementation
/**
* Observer Design Pattern
*
* Intent: Lets you define a subscription mechanism to notify multiple objects
* about any events that happen to the object they're observing.
*
* Note that there's a lot of different terms with similar meaning associated
* with this pattern. Just remember that the Subject is also called the
* Publisher and the Observer is often called the Subscriber and vice versa.
* Also the verbs "observe", "listen" or "track" usually mean the same thing.
*/
#include
#include
#include
class IObserver {
public:
virtual ~IObserver(){};
virtual void Update(const std::string &message_from_subject) = 0;
};
class ISubject {
public:
virtual ~ISubject(){};
virtual void Attach(IObserver *observer) = 0;
virtual void Detach(IObserver *observer) = 0;
virtual void Notify() = 0;
};
/**
* The Subject owns some important state and notifies observers when the state
* changes.
*/
class Subject : public ISubject {
public:
virtual ~Subject() {
std::cout << "Goodbye, I was the Subject.\n";
}
/**
* The subscription management methods.
*/
void Attach(IObserver *observer) override {
list_observer_.push_back(observer);
}
void Detach(IObserver *observer) override {
list_observer_.remove(observer);
}
void Notify() override {
std::list::iterator iterator = list_observer_.begin();
HowManyObserver();
while (iterator != list_observer_.end()) {
(*iterator)->Update(message_);
++iterator;
}
}
void CreateMessage(std::string message = "Empty") {
this->message_ = message;
Notify();
}
void HowManyObserver() {
std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
}
/**
* Usually, the subscription logic is only a fraction of what a Subject can
* really do. Subjects commonly hold some important business logic, that
* triggers a notification method whenever something important is about to
* happen (or after it).
*/
void SomeBusinessLogic() {
this->message_ = "change message message";
Notify();
std::cout << "I'm about to do some thing important\n";
}
private:
std::list list_observer_;
std::string message_;
};
class Observer : public IObserver {
public:
Observer(Subject &subject) : subject_(subject) {
this->subject_.Attach(this);
std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
this->number_ = Observer::static_number_;
}
virtual ~Observer() {
std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
}
void Update(const std::string &message_from_subject) override {
message_from_subject_ = message_from_subject;
PrintInfo();
}
void RemoveMeFromTheList() {
subject_.Detach(this);
std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
}
void PrintInfo() {
std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
}
private:
std::string message_from_subject_;
Subject &subject_;
static int static_number_;
int number_;
};
int Observer::static_number_ = 0;
void ClientCode() {
Subject *subject = new Subject;
Observer *observer1 = new Observer(*subject);
Observer *observer2 = new Observer(*subject);
Observer *observer3 = new Observer(*subject);
Observer *observer4;
Observer *observer5;
subject->CreateMessage("Hello World! :D");
observer3->RemoveMeFromTheList();
subject->CreateMessage("The weather is hot today! :p");
observer4 = new Observer(*subject);
observer2->RemoveMeFromTheList();
observer5 = new Observer(*subject);
subject->CreateMessage("My new car is great! ;)");
observer5->RemoveMeFromTheList();
observer4->RemoveMeFromTheList();
observer1->RemoveMeFromTheList();
delete observer5;
delete observer4;
delete observer3;
delete observer2;
delete observer1;
delete subject;
}
int main() {
ClientCode();
return 0;
}
Applicability
Use the Observer pattern when changes in one object require changes in others, and the set of dependent objects is unknown or dynamic.
This is common in GUI systems. For example, custom buttons may need to notify client code whenever they are pressed.
The Observer pattern allows objects implementing a subscriber interface to register for notifications and react automatically to events.
Use the pattern when objects should observe others only temporarily or conditionally.
Since subscriptions are dynamic, subscribers can join or leave the notification list at runtime.
⚖️ 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).
- You can establish relations between objects at runtime.
- Subscribers are notified in random order.
Relations with Other Patterns
-
Chain of Responsibility,
Command,
Mediator,
and Observer
define different ways of connecting senders and receivers:
- Chain of Responsibility passes a request along a chain until handled.
- Command creates unidirectional connections between senders and receivers.
- Mediator centralizes communication between components.
- Observer enables dynamic subscription and notification.
-
The difference between
Mediator
and
Observer
can be subtle:
Mediator reduces mutual dependencies by introducing a central object.
Observer establishes dynamic one‑way dependencies between publishers and subscribers.
A mediator can internally use Observer to notify components. However, Mediator can also be implemented without dynamic subscriptions.
If every component becomes a publisher, you end up with a distributed observer system instead of a centralized mediator.