Definition
The Observer Design Pattern is a behavioral design pattern that defines a one-to-many relationship between objects. When one object (the subject) changes its state, all its dependents (the observers) are notified and updated automatically.
It promotes loose coupling:
- The Subject doesn't need to know the concrete classes of its Observers.
- Observers can be added/removed at runtime dynamically.
Intent
- Decouple the subject and its observers, allowing them to vary independently.
- Ensure that changes in the subject are reflected in the observers without direct coupling.
Key Components
- Subject: Maintains a list of observers and notifies them of any state changes.
- Maintains a list of observers.
- Provides methods to attach/detach observers.
- Notifies all observers when its state changes.
- Observer Interface: Defines the method(s) used by the subject to notify observers.
- Abstract interface with an
update()
method. - Concrete Observers implement this method.
- Abstract interface with an
- Concrete Subject:
- Holds state of interest.
- When state changers, it calls
notify()
.
- Concrete Observer: Implements the observer interface and updates itself in response to changes in the subject.
When to Use
- When changes to one object need to automatically trigger updates in dependent objects.
- To implement event-driven programming or publish/subscribe mechanisms.
Example
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class ISubscriber {
public:
virtual void update() = 0;
virtual ~ISubscriber() {} // virtual destructor for interface
};
// Abstract Observable interface: a YouTube channel interface
class IChannel {
public:
virtual void subscribe(ISubscriber* subscriber) = 0;
virtual void unsubscribe(ISubscriber* subscriber) = 0;
virtual void notifySubscribers() = 0;
virtual ~IChannel() {}
};
// Concrete Subject: a YouTube channel that observers can subscribe to
class Channel : public IChannel {
private:
vector<ISubscriber*> subscribers; // list of subscribers
string name;
string latestVideo; // latest uploaded video title
public:
Channel(const string& name) {
this->name = name;
}
// Add a subscriber (avoid duplicates)
void subscribe(ISubscriber* subscriber) override {
if (find(subscribers.begin(), subscribers.end(), subscriber) == subscribers.end()) {
subscribers.push_back(subscriber);
}
}
// Remove a subscriber if present
void unsubscribe(ISubscriber* subscriber) override {
auto it = find(subscribers.begin(), subscribers.end(), subscriber);
if (it != subscribers.end()) {
subscribers.erase(it);
}
}
// Notify all subscribers of the latest video
void notifySubscribers() override {
for (ISubscriber* sub : subscribers) {
sub->update();
}
}
// Upload a new video and notify all subscribers
void uploadVideo(const string& title) {
latestVideo = title;
cout << "\n[" << name << " uploaded \"" << title << "\"]\n";
notifySubscribers();
}
// Read video data
string getVideoData() {
return "\nCheckout our new Video : " + latestVideo + "\n";
}
};
// Concrete Observer: represents a subscriber to the channel
class Subscriber : public ISubscriber {
private:
string name;
Channel* channel;
public:
Subscriber(const string& name, Channel* channel) {
this->name = name;
this->channel = channel;
}
// Called by Channel; prints notification message
void update() override {
cout << "Hey " << name << "," << this->channel->getVideoData();
}
};
int main() {
// Create a channel and subscribers
Channel* channel = new Channel("TheJat");
Subscriber* subs1 = new Subscriber("Ikka", channel);
Subscriber* subs2 = new Subscriber("Dukka", channel);
// Ikka and Dukka subscribe to TheJat
channel->subscribe(subs1);
channel->subscribe(subs2);
// Upload a video: both Ikka and Dukka are notified
channel->uploadVideo("Observer Pattern Tutorial");
// Ikka unsubscribes; Dukka remains subscribed
channel->unsubscribe(subs1);
// Upload another video: only Dukka is notified
channel->uploadVideo("Decorator Pattern Tutorial");
return 0;
}
Output:
[TheJat uploaded "Observer Pattern Tutorial"]
Hey Ikka,
Checkout our new Video : Observer Pattern Tutorial
Hey Dukka,
Checkout our new Video : Observer Pattern Tutorial
[TheJat uploaded "Decorator Pattern Tutorial"]
Hey Dukka,
Checkout our new Video : Decorator Pattern Tutorial
Normal program termination. Exit status: 0
Leave a comment
Your email address will not be published. Required fields are marked *