Observer lets one object (the subject) automatically notify a list of registered dependents whenever its state changes, without the subject needing to know anything about their concrete types.
public class StockTicker
{
// C# events are a built-in, language-level implementation of Observer.
public event Action<decimal>? PriceChanged;
private decimal _price;
public decimal Price
{
get => _price;
set
{
_price = value;
PriceChanged?.Invoke(_price); // notify every subscriber, whatever it is
}
}
}
public class PriceLogger
{
public void OnPriceChanged(decimal newPrice) => Console.WriteLine($"Price is now {newPrice}");
}
var ticker = new StockTicker();
var logger = new PriceLogger();
ticker.PriceChanged += logger.OnPriceChanged; // subscribe
ticker.Price = 101.50m; // triggers OnPriceChanged automatically
C# events, DOM events in the browser (addEventListener), and pub/sub message queues are all real-world implementations of exactly this pattern — a publisher that has no compile-time knowledge of who's listening, or how many listeners there are. The main pitfall in long-lived applications is forgetting to unsubscribe: a subscriber that's supposed to be garbage-collected but is still referenced by a subject's event list will never actually be collected, and will keep receiving notifications — a subtle memory leak that's easy to miss because nothing throws an error.