| Command-Pattern :👈 | 👉:Template-Method-Pattern |
Observer Pattern in C# |
π Observer Pattern (Reactive State Binding) in C#
The Observer Pattern is a behavioral design pattern where an object (called the Subject) maintains a list of dependents (called Observers) and notifies them automatically of any state changes.
In modern C#, this concept is often implemented using events, delegates, or Reactive Extensions (Rx) for reactive state binding.
π Key Concepts
- Subject (Observable): Holds the state and notifies observers when it changes.
- Observer: Subscribes to the subject and reacts to updates.
- Reactive Binding: Ensures UI or dependent components automatically update when the state changes.
βοΈ Why Use Observer Pattern?
- Decouples state management from UI or dependent logic.
- Enables reactive programming: changes propagate automatically.
- Useful in MVVM, UI frameworks (like WPF, MAUI), and real-time systems.
π Example in C#
Letβs build a simple Stock Price Tracker using the Observer Pattern.
using System;
using System.Collections.Generic;
// Observer Interface
public interface IObserver
{
void Update(decimal price);
}
// Subject Interface
public interface ISubject
{
void Attach(IObserver observer);
void Detach(IObserver observer);
void Notify();
}
// Concrete Subject
public class Stock : ISubject
{
private List<IObserver> _observers = new List<IObserver>();
private decimal _price;
public decimal Price
{
get => _price;
set
{
_price = value;
Notify(); // Notify observers when price changes
}
}
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (var observer in _observers)
{
observer.Update(_price);
}
}
}
// Concrete Observers
public class MobileApp : IObserver
{
public void Update(decimal price)
{
Console.WriteLine($"[MobileApp] Stock price updated: {price}");
}
}
public class WebApp : IObserver
{
public void Update(decimal price)
{
Console.WriteLine($"[WebApp] Stock price updated: {price}");
}
}
// Client
class Program
{
static void Main(string[] args)
{
Stock stock = new Stock();
IObserver mobileApp = new MobileApp();
IObserver webApp = new WebApp();
stock.Attach(mobileApp);
stock.Attach(webApp);
// Change stock price
stock.Price = 100.50m;
stock.Price = 102.75m;
// Detach one observer
stock.Detach(webApp);
stock.Price = 105.00m;
}
}
π Output
[MobileApp] Stock price updated: 100.50
[WebApp] Stock price updated: 100.50
[MobileApp] Stock price updated: 102.75
[WebApp] Stock price updated: 102.75
[MobileApp] Stock price updated: 105.00
β‘ Reactive State Binding in Modern C#
Instead of manually implementing the pattern, C# provides events and Reactive Extensions (Rx):
using System;
using System.Reactive.Subjects;
class Program
{
static void Main()
{
var stockPrice = new BehaviorSubject<decimal>(0);
// Observers subscribe
stockPrice.Subscribe(price => Console.WriteLine($"[MobileApp] Price: {price}"));
stockPrice.Subscribe(price => Console.WriteLine($"[WebApp] Price: {price}"));
// State changes
stockPrice.OnNext(100.50m);
stockPrice.OnNext(102.75m);
}
}
π Real-World Use Cases
- UI frameworks (WPF, MAUI, Blazor): Reactive binding between ViewModel and UI.
- Event-driven systems: Notifications, messaging, logging.
- Reactive programming: Streams of data (stock prices, sensor data, chat messages).
| Command-Pattern :👈 | 👉:Template-Method-Pattern |