Observer Design Pattern in C++



Observer Design Pattern is a way to make sure that when something important changes in one part of your program, all the other parts that care about it get updated right away. It's called a one-to-many relationship because one main object (the subject) can have many other objects (the observers) watching it. When the subject changes, it tells all its observers so they can update themselves. This is super helpful when you want different parts of your program to always show the latest information, but you don't want them to be tightly connected or mixed together.

For example, imagine you have a weather app with several display screens showing the current weather. The weather data is the subject, and the display screens are the observers. Whenever the weather changes, the weather data tells all the screens to update, so everyone always sees the newest weather. This way, you don't have to update each screen by hand because they all get the news automatically.

Sometimes people mix up the Observer Design Pattern with the Mediator Design Pattern. The difference is important: in the Observer Pattern, the subject keeps a list of observers and tells them when something changes. In the Mediator Pattern, there's a special mediator object in the middle that helps different objects talk to each other, so they don't talk directly. The Observer Pattern is all about keeping things in sync, while the Mediator Pattern is about organizing communication.

Observer Design Pattern Illustration

Components of Observer Design Pattern

The Observer Design Pattern consists of the following main components −

  • Subject − This is the main object that has some important information or state. When something changes inside the subject, it lets others know about it. The subject keeps a list of all the people (observers) who want to know when something changes. For example, in a weather app, the weather data is the subject because it knows the latest weather and tells others when it changes.
  • Observer − An observer is anyone who wants to know when the subject changes. Observers sign up with the subject, and whenever there is an update, the subject tells all its observers. In our weather app example, the display screens are observers because they show the latest weather whenever the weather data changes.
  • Concrete Subject − This is a real, working version of the subject. It actually stores the data and knows how to tell the observers when something changes. In the weather app, the WeatherData class is the concrete subject because it keeps the weather info and notifies the displays.
  • Concrete Observer − This is a real, working version of an observer. It knows how to react when the subject tells it about a change. In the weather app, the WeatherDisplay class is a concrete observer because it updates what it shows whenever the weather changes.

C++ Implementation of Observer Design Pattern

In this section, we will implement the Observer Design Pattern in C++. We will create a simple weather monitoring application to demonstrate how the pattern works.

Steps to Implement Observer Design Pattern in C++

Steps to Implement Observer Design Pattern

Follow these steps to implement the Observer Design Pattern in C++:

  • First, create an Observer interface. This is like a contract that says every observer must have an update function. This function will be called whenever there is a change.
  • Next, make a class for the actual observers (for example, a display screen). This class should use the Observer interface and define what happens when it gets updated (like showing the new weather).
  • Now, create a Subject interface. This is a contract for the main object (like the weather data) and says it must have ways to add, remove, and notify observers.
  • Then, make a class for the real subject (for example, the weather data). This class should use the Subject interface and keep a list of all observers. When the weather changes, it should tell all observers by calling their update function.
  • In your main program, make objects for the subject (weather data) and the observers (display screens).
  • Add the observers to the subject's list, then change the weather data to see how all the observers get updated automatically.

Example Code for Observer Design Pattern in C++

Here is a simple implementation of the Observer Design Pattern in C++

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

// Observer interface
class Observer {
public:
   virtual void update(float temperature, float humidity, float pressure) = 0;
};

// Concrete Observer class
class WeatherDisplay : public Observer {
private:
   float temperature;
   float humidity;
   float pressure;
public:
   void update(float temp, float hum, float pres) override {
      temperature = temp;
      humidity = hum;
      pressure = pres;
      display();
    }
   void display() {
      cout << "Weather Update - Temperature: " << temperature
           << ", Humidity: " << humidity
           << ", Pressure: " << pressure << endl;
    }
};

// Subject interface
class Subject {
public:
   virtual void attach(Observer* observer) = 0;
   virtual void detach(Observer* observer) = 0;
   virtual void notify() = 0;
};

// Concrete Subject class
class WeatherData : public Subject {
private:
   vector<Observer*> observers;
   float temperature;
   float humidity;
   float pressure;
public:
   void attach(Observer* observer) override {
      observers.push_back(observer);
   }
   void detach(Observer* observer) override {
      observers.erase(remove(observers.begin(), observers.end(), observer), observers.end());
   }
   void notify() override {
      for (Observer* observer : observers) {
         observer->update(temperature, humidity, pressure);
      }
   }
   void setMeasurements(float temp, float hum, float pres) {
      temperature = temp;
      humidity = hum;
      pressure = pres;
      notify();
   }
};

int main() {
   WeatherData weatherData;

   WeatherDisplay display1;
   WeatherDisplay display2;

   weatherData.attach(&display1);
   weatherData.attach(&display2);

   weatherData.setMeasurements(30.5, 65, 1013.1);
   weatherData.setMeasurements(28.3, 70, 1012.5);

   weatherData.detach(&display1);

   weatherData.setMeasurements(25.0, 80, 1011.8);

   return 0;
}

Following is the output of the above code −

Weather Update - Temperature: 30.5, Humidity: 65, Pressure: 1013.1
Weather Update - Temperature: 30.5, Humidity: 65, Pressure: 1013.1
Weather Update - Temperature: 28.3, Humidity: 70, Pressure: 1012.5
Weather Update - Temperature: 25.0, Humidity: 80, Pressure: 1011.8

Pros and Cons of Observer Design Pattern

The Observer Design Pattern offers several advantages and disadvantages −

Pros Cons
The Observer Design Pattern makes it easy to add new observers without changing the existing code. This means your program can grow and change over time without breaking things that already work. If you forget to remove observers when they are no longer needed, your program might use more memory than necessary. This can cause memory leaks, especially if the subject is destroyed but the observers are still around.
The subject and the observers do not need to know much about each other. This makes your code easier to change and maintain because you can update one part without affecting the other. If the subject changes its state very often, it will notify all observers each time. This can slow down your program if there are many observers or updates.
You can add or remove observers while the program is running. This means your program can react to changes and new requirements without stopping or restarting. Managing the list of observers and making sure everyone gets the right updates can make your code more complicated, especially in big programs.
You can use the same observer with different subjects. This helps you avoid writing the same code again and again. Observers are not always notified in a specific order. If your program depends on the order of updates, this can sometimes cause problems.

When to use Observer Design Pattern

The Observer Design Pattern is particularly useful in the following scenarios −

  • Use the Observer Design Pattern when you have one object that changes, and you want many other objects to know about this change automatically. For example, if you have a weather station and several display screens, you want all screens to show the new weather as soon as it changes.
  • This pattern is helpful when you don't know in advance how many things need to be updated. You can add or remove observers (like display screens) at any time, and they will always get the latest information.
  • It's also great when you want to keep your code simple and not have the main object (the subject) worry about who needs updates. The subject just sends out the update, and all observers get it automatically.
  • If you want to build a system where different parts react to changes or events, like in event-driven programs or notification systems, the Observer Design Pattern makes this easy and keeps everything organized.

Real-World Examples of Observer Design Pattern

Here are some real-world examples where the Observer Design Pattern is used −

  • GUI frameworks use this pattern so that when the data model changes, all the UI components (like buttons, labels, or charts) update automatically to show the latest information.
  • Event-driven systems let different parts of a program react to things that happen, like a button click or a new message. When the event source changes, all the listeners (observers) get notified and can respond right away.
  • On social media platforms, when someone you follow (the subject) posts something new, you (the observer) get an update instantly. This keeps you connected and always up to date with your favorite accounts.
  • Stock market apps use this pattern so that whenever a stock price changes, all the investors who are watching that stock get the latest price right away. This helps investors make quick decisions based on real-time data.
  • Messaging systems let you subscribe to topics or channels. When a publisher sends a new message, all the subscribers (observers) who are interested in that topic get the message automatically, so nobody misses important updates.
Real-World Use Cases of Observer Design Pattern

Conclusion

In this chapter, you learned about the Observer Design Pattern, how it works, its good and bad sides, and where it is used in real life. This pattern is very helpful for making programs where changes in one part need to be shared with many other parts, that keeps everything up to date and easy to manage.

Advertisements