Isaac.

design-patterns

Design Patterns: Observer

Learn the Observer pattern: decouple event producers from consumers.

By Emem IsaacJune 23, 20222 min read
#design patterns#observer#event-driven#publisher-subscriber#behavioral
Share:

A Simple Analogy

Imagine subscribing to a newspaper. Once you subscribe, the publisher sends you new editions automatically. You don't need to ask—they notify you. The Observer pattern works similarly: objects "subscribe" to events and get notified when something happens.


What Is the Observer Pattern?

Observer is a behavioral design pattern where one object (the Subject) maintains a list of dependent objects (Observers) and notifies them automatically when its state changes.


Why Use Observer?

  • Loose coupling: Subject doesn't need to know details about observers
  • Event-driven: Natural fit for event systems
  • Scalability: Easy to add or remove observers
  • Separation of concerns: Observers handle their own logic

Structure

Subject (Observable)
  └─ notify()
  └─ observers: List<Observer>

Observer (Interface)
  └─ update(event)

ConcreteObserver
  └─ update(event) implementation

C# Example

Step 1: Define Observer Interface

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

Step 2: Subject/Observable

public class Subject
{
    private List<IObserver> _observers = new();
    
    public void Subscribe(IObserver observer)
    {
        _observers.Add(observer);
    }
    
    public void Unsubscribe(IObserver observer)
    {
        _observers.Remove(observer);
    }
    
    public void Notify(string message)
    {
        foreach (var observer in _observers)
        {
            observer.Update(message);
        }
    }
}

Step 3: Concrete Observers

public class EmailNotifier : IObserver
{
    public void Update(string message)
    {
        Console.WriteLine($"Email sent: {message}");
    }
}

public class SlackNotifier : IObserver
{
    public void Update(string message)
    {
        Console.WriteLine($"Slack message: {message}");
    }
}

Step 4: Usage

var subject = new Subject();
subject.Subscribe(new EmailNotifier());
subject.Subscribe(new SlackNotifier());

subject.Notify("Order #123 shipped!");
// Output:
// Email sent: Order #123 shipped!
// Slack message: Order #123 shipped!

Real-World Use Cases

  • UI Events: Button clicks trigger handler updates
  • Event systems: Logger notified when errors occur
  • Pub/Sub systems: Message brokers (Kafka, RabbitMQ)
  • Stock tickers: Multiple subscriptions to price updates
  • MVC frameworks: Model changes notify Views

.NET Built-in: Events and Delegates

public class OrderService
{
    public event EventHandler<OrderEventArgs> OrderCreated;
    
    public void CreateOrder(Order order)
    {
        // Process order...
        OrderCreated?.Invoke(this, new OrderEventArgs { Order = order });
    }
}

// Subscribe
var service = new OrderService();
service.OrderCreated += (s, e) => Console.WriteLine($"New order: {e.Order.Id}");
service.CreateOrder(newOrder);

Related Concepts to Explore

  • Mediator pattern (alternative to Observer)
  • Publisher-Subscriber messaging
  • Reactive extensions (Rx.NET)
  • Event sourcing

Summary

The Observer pattern enables loose coupling between event producers and consumers. Use it when multiple objects need to react to state changes, keeping your system flexible and maintainable.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours