Observer Design Pattern


Here, we will see how to create Observer Design Pattern with example.

Observer Design Pattern

The Observer Design Pattern is a behavioral design pattern where an object (called the subject) maintains a list of its dependents (called observers) and notifies them of any state changes, usually by calling one of their methods. This pattern is useful when you need many objects to be updated in real-time with changes to a particular object.

Example

In this example, we will create a weather station that monitors and broadcasts weather data. Different displays (like a mobile app, a website widget, or a physical weather station) will subscribe to this data and update themselves automatically when the weather changes. We will explain in detail lator part of the article with code example.

Observer Design Pattern

Advantages of the Observer Pattern

  1. Loose Coupling -  The subject and the observers are loosely coupled because the subject doesn't need to know details about the observers. The subject only needs to know that the observers implement a certain interface.
  2. Dynamic Subscription -  Observers can subscribe or unsubscribe from notifications at any time, making the system more flexible.
  3. Real-Time Updates -  Observers receive updates as soon as the subject's state changes, ensuring real-time synchronization between the subject and observers.
  4. Reusability and Extensibility -  Observers can be reused and extended independently without modifying the subject.
  5. Scalability -  The pattern allows adding multiple observers easily, enabling scalability of notifications to different parts of the system.

When to Use the Observer Pattern

  1. Multiple Objects Need to be Informed -  Use it when several objects need to be notified of a change in another object. For example, in GUI applications where a change in the model should automatically update the views.
  2. Decoupling of Subject and Observer -  When you want to maintain a loose coupling between the object whose state changes and the objects that need to react to those changes.
  3. Dynamic Relationships -  When relationships between objects need to change at runtime, with observers being able to subscribe and unsubscribe dynamically.
  4. Event Handling Systems -  It is useful in event-driven systems, where different modules need to respond to specific changes or events.

Problems in a System without the Observer Pattern

  1. Tight Coupling -  Without the observer pattern, the subject class would need to keep references to all dependent objects, increasing coupling and making the system rigid.
  2. Code Duplication -  Without a well-defined mechanism like the observer pattern, you may end up writing similar notification logic across multiple places in your codebase.
  3. Manual Update Handling -  Without this pattern, you'd have to manually ensure that all dependent objects are notified when the state of the subject changes, which increases complexity and the likelihood of bugs.
  4. Scalability Issues -  If the number of dependent objects increases, maintaining and notifying them without an observer pattern becomes inefficient and prone to errors.

Example of the Observer Pattern

In this example, we’ll create a weather station that monitors and broadcasts weather data. Different displays (like a mobile app, a website widget, or a physical weather station) will subscribe to this data and update themselves automatically when the weather changes.

Components of the Observer Pattern

  1. Subject (Observable): This is the object whose state is being monitored (i.e., the weather station).
  2. Observers: These are the objects that subscribe to the subject and are notified whenever the subject’s state changes (i.e., weather displays).
  3. Observer Interface: Defines how observers should update themselves when the subject changes.
  4. Subject Interface: Defines how to register, remove, and notify observers.

Here’s a simple example in C# using a weather station system, where the weather station is the subject, and different display screens act as observers.

C# Code

using System;
using System.Collections.Generic;

// Observer Interface
public interface IObserver
{
    void Update(float temperature, float humidity, float pressure);
}

// Subject Interface
public interface IWeatherStation
{
    void RegisterObserver(IObserver observer);   
    void RemoveObserver(IObserver observer);     
    void NotifyObservers();                      
}

// Concrete Subject (WeatherStation)
public class WeatherStation : IWeatherStation
{
    private List<IObserver> observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherStation()
    {
        observers = new List<IObserver>();
    }

    public void RegisterObserver(IObserver observer)
    {
        observers.Add(observer);  // Add observer to the list
    }

    public void RemoveObserver(IObserver observer)
    {
        observers.Remove(observer);  // Remove observer from the list
    }

    public void NotifyObservers()
    {
        // Notify each observer about the new weather conditions
        foreach (IObserver observer in observers)
        {
            observer.Update(temperature, humidity, pressure);
        }
    }

    // Method to simulate new weather data coming in
    public void SetMeasurements(float temperature, float humidity, float pressure)
    {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        NotifyObservers();  // Notify all observers about the data change
    }
}

// Concrete Observer (WeatherDisplay)
public class WeatherDisplay : IObserver
{
    private float temperature;
    private float humidity;
    private float pressure;

    // Called by the subject when its state changes
    public void Update(float temperature, float humidity, float pressure)
    {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        Display();
    }

    // A simple method to display the weather conditions
    public void Display()
    {
        Console.WriteLine($"Current conditions: Temperature = {temperature}°C, Humidity = {humidity}%, Pressure = {pressure} Pa");
    }
}

// Main Program
public class Program
{
    public static void Main(string[] args)
    {
        // Create the subject (WeatherStation)
        WeatherStation weatherStation = new WeatherStation();

        // Create an observer (WeatherDisplay)
        WeatherDisplay display = new WeatherDisplay();

        // Register the display as an observer of the weather station
        weatherStation.RegisterObserver(display);

        // Simulate new weather data coming into the weather station
        weatherStation.SetMeasurements(25.0f, 65.0f, 1013.0f);  // 25°C, 65% humidity, 1013 Pa
        weatherStation.SetMeasurements(30.0f, 70.0f, 1009.0f);  // 30°C, 70% humidity, 1009 Pa
    }
}

Above Code Explanation

  • WeatherStation - The subject that holds the weather data (temperature, humidity, pressure) and notifies observers when these values change.
  • WeatherDisplay - The observer that displays the weather data when notified of changes.
  • IObserver - The interface that ensures all observers implement the Update method.
  • IWeatherStation - The interface that defines how to register, remove, and notify observers.

Output

Observer Design Pattern

Real-World Examples of the Observer Pattern

  1. Notification Systems - Many applications use the observer pattern for event notifications. For example, a social media app sends a notification to all followers when someone they follow posts a new update.
  2. Stock Market Tickers - A stock market system where multiple screens or apps (observers) are updated whenever stock prices (subject) change.
  3. Email and Messaging Systems - When a user sends a message, all subscribers to that message or email thread receive a notification.
  4. MVC Pattern - The Observer pattern is commonly used in the Model-View-Controller (MVC) architecture, where the model acts as the subject, and views act as observers. When the model changes, all the views are notified to update the display.

Application of Observer Design Pattern

  • Real-Time Systems - Systems that require real-time updates, like financial systems (e.g., stock price updates) or weather stations.
  • Event Handling - Used in GUI frameworks, such as in button click listeners and data binding mechanisms.
  • Distributed Systems - The Observer pattern can be useful in distributed systems where clients (observers) need to be notified of changes on the server (subject).
  • Multimedia Applications - In multimedia software, if one element (like a volume control) changes, it can notify all dependent elements like equalizers or visualizers to adjust accordingly.
  • Logging Frameworks - Used in logging systems where different components (observers) need to record various system events from a subject.

Prev Next

Top Articles

  1. What is JSON
  2. How to convert a javaScript object in JSON object
  3. Some Important JSON Examples
  4. Common JSON Interview Question