Observer Pattern in C++: What It Is and How It Works
observer pattern in C++ is a design pattern where an object, called the subject, keeps a list of dependents called observers and notifies them automatically of any state changes. It helps create a one-to-many relationship so that when the subject changes, all observers update themselves without tight coupling.How It Works
Imagine you have a newsletter service (the subject) and many subscribers (observers). When the newsletter publishes a new edition, it automatically informs all subscribers without needing to know details about each one. This is the core idea of the observer pattern.
In C++, the subject holds a list of observer objects. When its state changes, it calls a method on each observer to notify them. Observers then react to the change independently. This keeps the subject and observers loosely connected, making the system easier to maintain and extend.
Example
This example shows a simple subject that notifies observers when its value changes.
#include <iostream> #include <vector> #include <algorithm> // Observer interface class Observer { public: virtual void update(int value) = 0; virtual ~Observer() = default; }; // Subject class class Subject { int value_ = 0; std::vector<Observer*> observers_; public: void attach(Observer* obs) { observers_.push_back(obs); } void detach(Observer* obs) { observers_.erase(std::remove(observers_.begin(), observers_.end(), obs), observers_.end()); } void setValue(int val) { value_ = val; notify(); } void notify() { for (auto* obs : observers_) { obs->update(value_); } } }; // Concrete observer class ConcreteObserver : public Observer { std::string name_; public: ConcreteObserver(const std::string& name) : name_(name) {} void update(int value) override { std::cout << name_ << " received update: " << value << "\n"; } }; int main() { Subject subject; ConcreteObserver obs1("Observer1"); ConcreteObserver obs2("Observer2"); subject.attach(&obs1); subject.attach(&obs2); subject.setValue(10); subject.setValue(20); subject.detach(&obs1); subject.setValue(30); return 0; }
When to Use
Use the observer pattern when you want to create a system where multiple parts need to react to changes in one object without tightly linking them. For example, in a user interface, when data changes, multiple views can update automatically.
It is also useful in event-driven programming, like handling button clicks or data updates, where many listeners need to be informed. This pattern helps keep code clean and flexible by separating the subject from its observers.
Key Points
- The observer pattern creates a one-to-many dependency between objects.
- The subject notifies all registered observers of changes automatically.
- It promotes loose coupling and easier maintenance.
- Observers can be added or removed at runtime.