👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Behavioral Design Pattern - Observer

Behavioral Design Pattern - Observer

Design Pattern

10 Articles

Improve

In this article, let's learn about Observer Design Pattern in .NET.

Table of Contents

  1. Introduction
  2. Structure
  3. Use Cases
  4. Advantages
  5. Disadvantages
  6. Related Patterns
  7. Summary

Introduction

In this article, we'll explore the Observer pattern, a behavioral design pattern used to create a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. This pattern is also known as the Publish-Subscribe or Pub/Sub pattern. We'll start by explaining the pattern using a practical example. We'll implement a simplified order management system where different parts of an order need to stay in sync. Then, we'll delve into the pattern's structure, use cases, consequences, and related patterns. Let's get started!

The Observer pattern, as described in the Gang of Four design patterns book, aims to define a dependency between objects such that when one object changes, all its dependents are notified and updated automatically. This pattern is commonly used in applications where data changes need to propagate throughout the system without tightly coupling components.

Example Scenario: Order and OrderItem in an Order Management System

Let's consider a scenario where we manage orders and their associated items in an order management system. When an OrderItem (like the quantity or price of an item) is updated, the Order needs to recalculate its total to reflect these changes. This setup mirrors the Observer pattern:

  • OrderItem: Represents the individual items in an order, with properties such as quantity and unit price.
  • Order: Represents the overall order, which needs to keep track of total cost and other details based on its items.

Rather than the Order directly querying each OrderItem for changes, we can use the Observer pattern to notify the Order whenever an OrderItem is updated. This way, the system remains flexible and easy to extend.

Structure

The Observer pattern involves several key components:

  1. Subject: The object that holds the state and notifies observers of any state changes. In our example, the OrderItem acts as the subject.
  2. Observer: An interface or abstract class defining the method to be called when the subject's state changes. Here, Order is our observer interface.
  3. Concrete Subject: The specific object holding the state of interest. For this example, it's the OrderItem class.
  4. Concrete Observer: The specific implementation of the observer interface. In our case, each Order implements an observer to track its changes.

Here's how we can implement the Observer pattern in our order management system:

Code Sample - Publisher Code Sample - Observer Pattern

In the above code we are adding Observer (Order) using AddObserver and removing Observer (Order) using RemoveObserver. NotifyOrderItemProcessed notifies all subscribed observers (order) by calling their ReceiveOrderItemProcessedNotification method. OrderItem implements the above abstract class and calls NotifyOrderItemProcessed method whenever there is a change in OrderItem.

Code Sample - Listener Code Sample - Observer Pattern

In the above code OrderViewModel listens for changes in OrderItemViewModel instances and recalculates the total amount using CalculateTotalAmount whenever any item is updated, ensuring the total is always accurate.

Demo - Observer Pattern Demo

Let's try Observer Demo, Click on the Add Order Item and Remove Order Item and change Quantity and Price to see the observer pattern in action. The results will be displayed at the bottom of table.

Code Sample - Observer Pattern Demo

Quantity Price Line Amount
Total ¤0.00

Use Cases

The Observer pattern is beneficial in several scenarios:

  1. Dynamic Relationships: When the number of dependents (observers) that need to be updated can change at runtime, like dynamically adding or removing items from an order.
  2. Decoupling Components: To avoid tight coupling between components, like separating order calculation logic from item management.
  3. Event Handling Systems: In scenarios like GUI frameworks, where user interactions need to notify various components without tightly binding them together.

Advantages

Loose Coupling: Subjects and observers remain loosely coupled, which allows for greater flexibility and easier maintenance.

Disadvantages

  • Potential Performance Impact: If not managed carefully, especially with a large number of observers, the notification process might lead to performance issues.
  • Change Cascades: Unintended cascades of changes can occur if observers can change the state of subjects in response to notifications.

The Observer pattern is closely related to several other design patterns:

  • Mediator: Centralizes complex communication and control logic between objects, effectively reducing dependencies.
  • Command: Encapsulates a request as an object, thereby allowing for parameterization and queuing of requests.
  • Chain of Responsibility: Allows a request to pass along a chain of potential handlers until it is processed.

Summary

In this module, we explored the Observer pattern through the lens of an order management system. We saw how this pattern allows for automatic updates and notifications across related components, promoting loose coupling and flexibility. We also covered use cases, consequences, and related patterns to provide a comprehensive understanding of its applications.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Design Pattern
  • Behavioral
  • Observer