Observer Pattern in C#: What It Is and How It Works
Observer Pattern in C# is a design pattern where an object, called the subject, keeps a list of dependents called observers and notifies them automatically of any state changes. It helps create a one-to-many relationship so that when the subject changes, all observers get updated without tight coupling.How It Works
Imagine you have a newsletter service where many people want to get updates when a new issue is released. Instead of telling each person individually, the service keeps a list of subscribers and sends them the update automatically. This is how the observer pattern works.
In C#, the subject is the object that holds important data or state. Observers are objects that want to know when the subject changes. The subject keeps track of all observers and notifies them by calling a method on each observer whenever its state changes. This way, observers stay updated without the subject needing to know details about them.
Example
This example shows a simple weather station (subject) that notifies display devices (observers) when the temperature changes.
using System; using System.Collections.Generic; // Subject interface public interface ISubject { void RegisterObserver(IObserver observer); void RemoveObserver(IObserver observer); void NotifyObservers(); } // Observer interface public interface IObserver { void Update(float temperature); } // Concrete Subject public class WeatherStation : ISubject { private List<IObserver> observers = new List<IObserver>(); private float temperature; public void RegisterObserver(IObserver observer) { observers.Add(observer); } public void RemoveObserver(IObserver observer) { observers.Remove(observer); } public void NotifyObservers() { foreach (var observer in observers) { observer.Update(temperature); } } public void SetTemperature(float temp) { temperature = temp; NotifyObservers(); } } // Concrete Observer public class TemperatureDisplay : IObserver { private string name; public TemperatureDisplay(string name) { this.name = name; } public void Update(float temperature) { Console.WriteLine($"{name} display: Temperature updated to {temperature}°C"); } } class Program { static void Main() { WeatherStation station = new WeatherStation(); TemperatureDisplay display1 = new TemperatureDisplay("Living Room"); TemperatureDisplay display2 = new TemperatureDisplay("Bedroom"); station.RegisterObserver(display1); station.RegisterObserver(display2); station.SetTemperature(25.3f); station.SetTemperature(26.7f); station.RemoveObserver(display1); station.SetTemperature(27.5f); } }
When to Use
Use the observer pattern when you want to create a system where multiple parts need to react to changes in one object without tightly linking them together. It is great for event handling, user interface updates, or any situation where changes in one place should automatically update others.
For example, in a chat app, when a new message arrives, all open chat windows can update automatically. Or in a stock market app, when prices change, all interested displays update without the price source needing to know about each display.
Key Points
- The observer pattern creates a one-to-many dependency between objects.
- Subjects notify observers automatically when their state changes.
- It reduces tight coupling between objects, making code easier to maintain.
- Commonly used in event-driven programming and UI updates.