Skip to main content

Observer Design Pattern - A Beginner's Guide with an Airport Baggage System

Are you in the market for learning how to implement the Observer Design Pattern? This tutorial will show you how to apply this pattern with C# and diagrams to make your understanding even better.

· By Christian Schou Køster · 9 min read

Welcome to my beginner-friendly Observer design pattern guide. We will examine the foundations of the Observer pattern in this article and show how to use it using the example of an airport baggage system.

What Is The Observer Design Pattern?

The Observer design pattern is a behavioral design pattern that creates a one-to-many dependency between objects. As a result, whenever the state of one object, known as the subject, changes, all of its dependent objects, known as observers, are automatically notified and updated. The subject and observers are decoupled, allowing for a flexible and loosely coupled system. 🙌

Why Use The Observer Pattern?

Imagine a situation where your application has several modules or components that must respond to modifications in the state of a specific object. One strategy would be to tightly couple these parts together, creating a complex and challenging codebase. The Observer pattern can help in this situation.

The Observer pattern allows you to create a clear separation of concerns where the subject-object doesn't need to be aware of its observers and where observers can be added or removed without affecting the subject. This encourages modularity, extensibility, and reuse, which strengthens your code and makes it simpler to maintain. 👏

Airport Baggage System Example

I will walk you through my Airport Baggage System (C# project) to show the Observer design pattern in action. Multiple baggage handlers must be notified when a new bag is added to the system or removed from it. Based on these notifications, the baggage handlers will then carry out their respective tasks.

When walking you through the code found in my Airport Baggage System's GitHub repository throughout this article, I will be outlining each step of the implementation procedure. Do not worry if you are unfamiliar with design patterns or have little programming experience. We'll go through it step-by-step to make it simple for you to understand and follow along.

design-patterns/Behavioral/Observer/AirportBaggageSystem at main · Christian-Schou/design-patterns
A Place to store all Design Pattern Example projects from my tutorials on the TWC blog. - design-patterns/Behavioral/Observer/AirportBaggageSystem at main · Christian-Schou/design-patterns

So let's begin by having a look at the fundamental ideas and structure of the Observer design pattern!

Understanding the Observer Design Pattern

Let's take a moment to comprehend the fundamental ideas and architecture of the Observer design pattern before delving into the implementation specifics.

Observer pattern - Wikipedia

The Participants: Subject and Observer

In the Observer design pattern, there are two key participants: the Subject and the Observer.

  • Subject - The object holding the state under observation is referred to as the subject. It offers ways to add, take away, and alert observers to any state changes. The Subject manages the subscriptions of the observers on a list that is kept up to date. The ConcreteSubject class in our illustration represents the actual implementation of the Subject.
  • Observer - The object that requests to be informed when the Subject's state changes is known as the Observer. Every time a change takes place, the Subject calls the update method, which is defined by this sentence. The Observer can then act appropriately based on the notification that was received. The ConcreteObserver class in our example represents the actual implementation of the Observer.
💡
In the Observer design pattern, the ConcreteSubject and ConcreteObserver classes represent the concrete implementations of the Subject and Observer, respectively. These concrete classes extend or implement the abstract Subject and Observer interfaces, providing the specific implementation details required for the Observer pattern to work in a particular context.

How It Works

A one-to-many relationship is established between the Subject and the Observer by the Observer design pattern. The Subject automatically alerts all "logged-in" Observers whenever its state changes. This decoupling promotes loose coupling and modularity by ensuring that the Subject is not required to know any specifics about its Observers.

observer, observer design pattern, observer pattern
Observer Design Pattern

Here's a high-level overview of how the Observer design pattern works:

  1. The Subject offers ways to add, delete, and notify Observers, as well as a list of them.
  2. Observers sign up with the Subject to receive notifications. This makes it possible to associate multiple Observers with a single Subject.
  3. When the state of the Subject changes, the notifyObservers method is invoked. This method iterates through the list of registered Observers and calls each one's update method.
  4. Upon receiving the notification, each Observer runs its own custom logic that was specified in the update method.
  5. The Subject and Observers continue to be only loosely coupled because the Subject only understands the Observer interface and is unaware of any particular concrete Observer implementations.

By using this pattern, you can quickly add new Observers or make changes to those that are already there without changing the Subject or creating a close coupling between it and the Observers. The Observer design pattern's main benefits are its adaptability and maintainability.

The implementation of the Observer pattern in our airport baggage system example will be discussed in more detail in the following section. I will step-by-step walk you through the code, describing the function of each part and how they relate to one another.

Implementing the Observer Design Pattern

Now that you have a solid understanding of the Observer design pattern, let's use my Airport Baggage System example to delve into the implementation specifics. I'll take you step-by-step through the code while explaining each component's function and how it interacts with others.

About the author

Christian Schou Køster Christian Schou Køster
Updated on Sep 30, 2025