Observer Pattern
The Observer Design Pattern is a behavioral design pattern that allows one-to-many dependency relationships between objects.
In this pattern, when one object (called the subject or observable) changes its state, all its dependent objects (called observers) are notified and updated automatically.
The pattern follows a one-to-many dependency relationship, where multiple observer objects are dependent on a single subject.
Table of Contents
Observer Pattern Example:
Consider a newspaper subscription scenario. A newspaper publisher (the subject) has multiple subscribers (the observers). Whenever a new edition of the newspaper is published (state change in the subject), all the subscribers should be notified and receive the latest edition.
Observer Pattern C++ Code Example:
Let’s implement the Observer Design Pattern in C++ using a simple newspaper subscription example.
#include <iostream>
#include <vector>
class Observer {
public:
virtual void update(const std::string& message) = 0;
};
class Subject {
private:
std::vector<Observer*> observers;
std::string message;
public:
void addObserver(Observer* observer) {
observers.push_back(observer);
}
void removeObserver(Observer* observer) {
// Remove the observer from the vector
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notifyObservers() {
for (Observer* observer : observers) {
observer->update(message);
}
}
void setMessage(const std::string& newMessage) {
message = newMessage;
notifyObservers();
}
};
class Subscriber : public Observer {
private:
std::string name;
public:
Subscriber(const std::string& name) : name(name) {}
void update(const std::string& message) override {
std::cout << name << " received the latest edition. Headlines: " << message << "\n";
}
};
int main() {
Subject newspaperPublisher;
Subscriber subscriber1("Alice");
Subscriber subscriber2("Bob");
newspaperPublisher.addObserver(&subscriber1);
newspaperPublisher.addObserver(&subscriber2);
newspaperPublisher.setMessage("Breaking news: AI helps humans in various fields!");
newspaperPublisher.removeObserver(&subscriber2);
newspaperPublisher.setMessage("Sports: Local team wins the championship!");
return 0;
}
Observer Pattern Explanation of the Code:
- We have an
Observer
class, which represents the interface for all observers. It has a pure virtual functionupdate
that will be implemented by concrete observer classes. - The
Subject
class is the observable, which maintains a list of observers and notifies them whenever its state (in this case, themessage
) changes. It provides methods to add, remove, and notify observers. - The
Subscriber
class represents individual subscribers who will receive updates from the newspaper publisher. It implements theupdate
method to process the updates.
Applications of Observer Design Pattern:
- GUI frameworks: It is commonly used in graphical user interfaces (GUI) to handle events and updates between different components.
- Event handling systems: The observer pattern is used to manage event-driven systems where various objects need to react to events.
- Distributed systems: In distributed systems, it facilitates communication between different components or modules.
Pros of Observer Design Pattern:
- Loose coupling: The subject and observers are loosely coupled, meaning changes in one do not affect the other significantly.
- Easy to extend: New observers can be added without modifying the subject, making the pattern easy to extend.
- Allows multiple observers: A subject can notify multiple observers without knowing their specific identities.
Cons of Observer Design Pattern:
- Order of notification: The order in which observers are notified might be unpredictable, depending on the implementation.
- Performance concerns: If the number of observers is very large, it may impact performance due to multiple notifications.
In summary, the Observer Design Pattern is useful when you have one-to-many relationships between objects, and you want to ensure that changes in one object are automatically propagated to its dependents. It encourages loose coupling and facilitates event-driven communication between different components in a system.