What is the Observer Design Pattern?

Göksu Deniz
8 min readDec 25, 2022

--

Image is created by DALL-E 2 AI

The observer design pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.

The observer pattern is also known as the publish-subscribe pattern. It is used to allow loose coupling between objects, so that an object need not know the details of how its state changes are being used, but can instead provide a simple method for other objects to register an interest in being notified of those changes.

In the observer pattern, the subject is often implemented as a simple data structure, such as a list, that stores a list of references to the observer objects. When the state of the subject changes, it sends a notification message to all of the registered observers, which can then update their own state as needed.

The observer pattern is a useful design pattern to use when you need to have one or more objects receive notifications when the state of another object changes, but you don’t want the objects to be tightly coupled. This can be particularly useful in situations where you need to maintain consistency between related objects, but don’t want the complexity of creating and maintaining explicit links between the objects.

Imagine you have a group of friends who all love to play soccer. You decide to create a soccer club, and you invite all of your friends to join. You are the captain of the club, and you are responsible for organizing the games and making sure everyone knows when and where to play.

One day, you decide to change the location of the next game. You don’t want to call or text all of your friends separately to let them know about the change, so instead you send a message to the entire club using a special messaging app that you all use. When your friends receive the message, they can check the app to see when and where the game will be played.

In this example, you are the subject and your friends are the observers. The subject (you) maintains a list of the observers (your friends) and sends them a notification (the message on the app) whenever the state of the subject (the location of the game) changes. The observers (your friends) can then update their own state (their plans for the game) as needed.

This is similar to how the observer design pattern works in software development. The subject is an object that maintains a list of observer objects, and the observers are notified when the state of the subject changes. The observers can then update their own state as needed based on the notification they receive from the subject.

What did the observer say to the subject when it was feeling left out? “Don’t worry, I’ll always be here to keep an eye on you.”

One common use case for the observer pattern is in UI development, where the subject represents a model or data source and the observer represents a view that displays the data. When the data in the model changes, the subject can send a notification to the view, which can then update itself to reflect the new data. This allows the view to stay in sync with the model without the need for the view to constantly poll the model for updates.

Another common use case for the observer pattern is in event-driven systems, where the subject represents an event source and the observer represents an event handler. When an event occurs, the subject can send a notification to the observer, which can then perform some action in response to the event. This allows for a more dynamic and flexible system, as the observer can respond to events in real-time without the need for the event source to know the details of how the event will be handled.

Here is a simple example of how the observer design pattern might be implemented in C#:

First, we will define an interface for the observers:

public interface IObserver
{
void Update(string message);
}

Next, we will define a class for the subject:

public class Subject
{
private List<IObserver> observers = new List<IObserver>();

public void Attach(IObserver observer)
{
observers.Add(observer);
}

public void Detach(IObserver observer)
{
observers.Remove(observer);
}

public void Notify(string message)
{
foreach (IObserver observer in observers)
{
observer.Update(message);
}
}
}

The subject maintains a list of observer objects and provides methods for adding or removing observers from the list. It also has a Notify method that sends a notification message to all of the registered observers.

Finally, we will define a class for the observers:

public class Observer : IObserver
{
private string name;

public Observer(string name)
{
this.name = name;
}

public void Update(string message)
{
Console.WriteLine($"{name} received message: {message}");
}
}

The observer class implements the IObserver interface and provides an Update method that is called when it receives a notification from the subject.

To use this example, you would first create an instance of the Subject class, and then create one or more instances of the Observer class. You would then register the observer instances with the subject using the Attach method, and whenever you want to send a notification to the observers, you would call the Notify method on the subject.

Here is an example of how this might be used in a main program:

Subject subject = new Subject();
Observer observer1 = new Observer("Observer 1");
Observer observer2 = new Observer("Observer 2");

subject.Attach(observer1);
subject.Attach(observer2);

subject.Notify("The game has been rescheduled for 2pm.");

This would output the following to the console:

Observer 1 received message: The game has been rescheduled for 2pm.
Observer 2 received message: The game has been rescheduled for 2pm.

What did the subject say to the observer when it finally got a notification? “It’s about time! I’ve been waiting for you to notice me!”

Imagine you have a news website that displays the latest headlines from various sources. You want to create a system that allows users to subscribe to specific sources and receive notifications whenever new articles are published.

In this case, the news sources could be implemented as the subject, and the users who have subscribed to a source could be implemented as the observers. The subject would maintain a list of its observers and provide a method for adding or removing observers from the list. When a new article is published, the subject would send a notification to all of the registered observers, who could then update their own state (e.g., by displaying a notification to the user or adding the new article to a list of articles to read).

Here is some example code that illustrates how this might be implemented in C#:

public interface INewsSource
{
string Name { get; }
void Attach(IUser user);
void Detach(IUser user);
void Notify(Article article);
}

public class NewsSource : INewsSource
{
private string name;
private List<IUser> users = new List<IUser>();

public string Name => name;

public NewsSource(string name)
{
this.name = name;
}

public void Attach(IUser user)
{
users.Add(user);
}

public void Detach(IUser user)
{
users.Remove(user);
}

public void Notify(Article article)
{
foreach (IUser user in users)
{
user.Update(article);
}
}
}

public interface IUser
{
string Name { get; }
void Update(Article article);
}

public class User : IUser
{
private string name;

public string Name => name;

public User(string name)
{
this.name = name;
}

public void Update(Article article)
{
Console.WriteLine($"{name} received notification of new article: {article.Title}");
}
}

To use this example, you would first create instances of the NewsSource class for each news source you want to offer (e.g., "CNN", "BBC", etc.), and then create instances of the User class for each user who wants to subscribe to one or more sources. You would then register the users with the sources they are interested in using the Attach method, and whenever a new article is published, you would call the Notify method on the appropriate news source with the new article as an argument.

The observer design pattern is widely used in the development of pub-sub systems, and many companies and organizations use it to implement real-time notifications and other types of distributed event handling. Here are a few examples of how the observer design pattern might be used in a pub-sub system:

  1. Real-time notifications: One common use case for the observer design pattern in pub-sub systems is to provide real-time notifications to users or other clients. For example, a social media platform might use the observer design pattern to send notifications to users when someone likes their post or comments on it.
  2. Data synchronization: The observer design pattern can also be used to synchronize data between multiple clients or devices. For example, a cloud storage service might use the observer pattern to send updates to clients whenever a file is added, modified, or deleted in the cloud.
  3. Event tracking: The observer design pattern can also be used to track events and trigger actions based on those events. For example, an e-commerce platform might use the observer pattern to track purchases and send emails to customers with personalized product recommendations based on their purchase history.
  4. Network communication: The observer design pattern is also often used to facilitate communication between different parts of a network. For example, a messaging app might use the observer pattern to send messages between users and update the user interface with new messages as they are received.

Conclusion

The observer design pattern is a software design pattern that allows an object, called the subject, to maintain a list of its dependents, called observers, and to notify them automatically of any state changes. The main purpose of the observer pattern is to allow loose coupling between objects, so that an object need not know the details of how its state changes are being used, but can instead provide a simple method for other objects to register an interest in being notified of those changes.

There are several benefits to using the observer design pattern:

  1. Decoupling: One of the main benefits of the observer pattern is that it allows you to decouple the objects that are being observed from the objects that are observing them. This means that the observed objects do not need to know anything about the observer objects, and vice versa. This can make it easier to change or modify the observer objects without affecting the observed objects, and vice versa.
  2. Reusability: The observer pattern can also make it easier to reuse code, because the observer objects can be used in multiple contexts without being tightly coupled to the observed objects.
  3. Flexibility: The observer pattern also allows you to add or remove observer objects dynamically, which can be useful if you need to change the behavior of your system at runtime.
  4. Extensibility: The observer pattern can also make it easier to extend your system, because you can add new observer objects without modifying the observed objects.

Overall, the observer design pattern is a useful tool for implementing distributed event handling systems and for maintaining consistency between related objects in a flexible and decoupled manner.

Thanks for reading! If you found the article helpful, you can clap and follow. So you will notified of new articles.

# Reference

It was created with the help of ChatGPT AI.

--

--

Göksu Deniz

Software Engineer, passionate about creating efficient solutions. Skilled in mentoring teams to deliver successful projects. Always exploring new tech trends.