×

Observer Design Pattern in C++

The Observer design pattern is a behavioural design pattern that allows an object (known as the subject) to notify other objects (known as observers) when its state changes. This is useful in cases where you want to maintain consistency between related objects without making the objects tightly coupled.

Example

Here is an example of the Observer design pattern in C++:

#include <iostream>
#include <vector>
// Forward declaration of the Subject class
class Subject;
// The Observer class has a virtual update function that can be
// overridden by derived classes. It also has a constructor that
// takes a Subject as an argument and registers itself as an observer
// of that subject.
class Observer {
 public:
Observer(Subject* subject) {
    subject_ = subject;
    subject_->Attach(this);
  }
  virtual ~Observer() {}
  virtual void Update() = 0;
 private:
  Subject* subject_;
};
// The Subject class has a vector of observers and functions to add
// or remove observers from the vector. It also has a virtual function
// called Notify that can be overridden by derived classes.
class Subject {
 public:
Subject() {}
  virtual ~Subject() {}
  void Attach(Observer* observer) {
    observers_.push_back(observer);}
  void Detach(Observer* observer) {
    for (size_ti = 0; i<observers_.size(); ++i) {
      if (observers_[i] == observer) {
observers_.erase(observers_.begin() + i);
break;}   } }
  virtual void Notify() {
    for (auto observer : observers_) {
      observer->Update();} }
 private:
std::vector<Observer*> observers_;};
// A concrete subject class that stores a single integer value.
// It has a function called SetValue that updates the value and
// notifies observers when the value changes.
class IntSubject : public Subject {
 public:
IntSubject() : value_(0) {}
  int GetValue() const { return value_; }
  void SetValue(int value) {
    if (value_ != value) {
      value_ = value;
Notify();}}
private:
  int value_;  };
// A concrete observer class that displays the value of an IntSubject
class IntObserver : public Observer {
public:
IntObserver(IntSubject* subject) : Observer(subject) {}
  void Update() override {
std::cout<< "IntObserver: Subject value is now "
<<static_cast<IntSubject*>(subject_)->GetValue() << std::endl;
};
  }
int main() {
IntSubject subject;
IntObserver observer1(&subject);
IntObserver observer2(&subject);
subject.SetValue(5);
subject.SetValue(10);
subject.SetValue(10);  // No update should be triggered
  return 0;
}

This example defines a Subject class with functions to attach and detach observers and a virtual Notify function that derived classes can override.

When to Use Observer Design?

It would be best if you used the Observer design pattern in C++ to establish a one-to-many relationship between objects, such that when one object (the subject) changes state, all the dependent objects (the observers) are notified and updated automatically.

This pattern is useful in cases where you want to maintain consistency between related objects without making the objects tightly coupled. For example, consider a graphical user interface (GUI) where multiple widgets (observers) display the same data and need to be updated whenever the data changes. Using the Observer pattern, you can design the widgets and the data as separate classes and have the widgets register themselves as observers of the data. When the data changes, it can notify all its registered observers, then update its display.

Another example where the Observer pattern can be useful is in a stock ticker application, where multiple clients (observers) are interested in receiving updates on the latest stock prices. The stock ticker (the subject) can notify all the registered clients (the observers) whenever the prices change.

In general, you should use the Observer pattern when:

  • There is a one-to-many relationship between objects, such that when one objects changes state, all its dependents are notified and updated automatically.
  • You want to abstract the details of the objects that depend on the subject from the subject itself.
  • You want to change the dependencies between objects at runtime.You want to minimize the coupling between objects, such that the subject and its dependents are loosely coupled.

Advantages of Observer Design Pattern

The Observer design pattern has several advantages:

  • It decouples the subject from its observers, which makes it easier to change the subject and the observers independently.
  • It allows a subject to notifying its observers generically without the subject knowing the specifics of the observers.
  • It allows a subject to have any number of observers, which can be added or removed at runtime.
  • It allows observers to be notified of a subject's state changes as soon as they occur, rather than polling the subject for updates.
  • It allows observers to be added or removed from a subject dynamically, at runtime, without modifying the subject's code.

Related Topics

What are local class and global class in C++

In C++, a class is a fundamental block that achieves object-oriented programming. The class holds its data members and member functions. Objects help to access the data elements and functions....

4 minutes read.

Print Table Using Do while Loop in C++

Multiplication Table In mathematics, a table is created by multiplying a certain number by all of the counting numbers, i.e., 1, 2, 3, 4, 5, 6, and so on. It is...

4 minutes read.

Abstract class in C++

In this article, you will get exposure to an abstract class in C++. We will discuss this topic using some practical examples too. To understand the abstract classes, you should...

6 minutes read.

C++ If-else-if

Introduction: If-else-if control statement is an if statement used with an optional else if control statement to check multiple conditions. In this control statement, when any one of the condition returns...

4 minutes read.

C++ Mutable keyword

C++ mutable keyword Mutable class storage specifier in C++ Storage class specifiers in C are auto, register, static, and external. Typedef is also considered as a specifier of the storage...

4 minutes read.

How to initialize a dynamic array in C++

Regular arrays or static arrays have a predetermined size or fixed size. Change in the size of regular arrays is not possible. The memory size for static arrays determines at compile...

4 minutes read.

C++ Bitwise XOR Operator

Exclusive OR is another name for the bitwise XOR operator. The ‘^’ is used to indicate it. It operates at the bit level of the operands, as the name implies....

4 minutes read.

Reverse function in C++

The function std::reverse() is included in the standard template library of C++. It takes in a beginning and ending iterator, reversing the order. To use the reverse statement, we need...

2 minutes read.

Dynamic Binding in C++

The notion of dynamic binding solved the challenges associated with static binding. Static binding refers to bindings that can be resolved by the compiler at runtime. All storage, stationary, and...

3 minutes read.

C++ Functions

In other programming languages, a function is referred to as a process or a subroutine. We can design functions to execute any task. A function can be used repeatedly. It...

5 minutes read.

C++ int into String

Data type conversion is a standard editing process. You may need to convert variable from one type of data to another in a variety of situations. There are two ways...

5 minutes read.

rand() and srand() in C / C++

In this tutorial, we'll explore the syntax, usage, and examples of the C++ STL functions rand() and srand(). What exactly is rand()? The C++ STL's built-in rand() function is defined in the...

3 minutes read.

Name Mangling and extern in C++

Name Mangling and Function Overloading: Function overloading is a feature offered by C++. As long as each function accepts various parameters, we can use this to write many functions with the...

4 minutes read.

Armstrong Number Program in C++

Let's first define Armstrong number before writing the C++ program to check whether the number is Armstrong or not. The sum of the cubes of its digits is equal to the...

2 minutes read.

Binary Search in C++

The binary search in the C++ programming language will be discussed. By continually halves the array and then seeking specified items from a half array; binary search is a technique...

8 minutes read.

Factory Method for Designing Pattern in C++

In C++, the factory method is a type of conditional design pattern. The factory method is related to creating a new object in C++. With the help of a factory...

3 minutes read.

Containership in C++

In C++, it is possible to create an object in one class into another class, and that object is a member of another class. This relationship is known as a...

4 minutes read.

C++ Overloading

C++ Overloading is a condition when two or more members have the same name with different parameter type or a different number of parameter. C++ overloading is two types: Function...

1 minute read.

Object Slicing in C++

In this article, we will learn about Object slicing. When an object from a derived class is assigned to an object from a base class in C++, these extra attributes...

3 minutes read.

Priority Queue in C++

Priority Queue in C++ Introduction: We have already come across Queues by concluding that they are linear data structures that follow FIFO (First-In-First-Out) approach. We had also discussed the syntax of queues...

4 minutes read.