Introduction to Observer Pattern in .NET

What is the Observer Pattern?

The Observer Design Pattern is all about how objects interact when one changes state. Think of it like a notification system where one object, the subject, notifies a group of other objects, the observers, whenever it undergoes a change.

It’s like setting up a system where various objects are keeping an eye on one main object. When that main object changes, all the others are instantly informed and can update themselves accordingly.

  • This pattern helps in keeping our code neat and organised. By separating the subject from its observers, we create a more modular and easy-to-maintain design.
  • Another benefit is that it keeps things flexible. The subject doesn’t need to know specific details about its observers, so we can add or remove observers without messing with the subject itself.
  • The magic happens through notifications. Whenever the subject changes, it sends out notifications to all its observers, allowing for dynamic and coordinated responses from multiple objects. It’s like keeping everyone in the loop so they can react appropriately.

Components of Observer Design Pattern

Subject

The subject keeps track of a roster of observers, sometimes called subscribers or listeners. It offers functions for adding and removing observers on-the-fly, and it defines a way to inform observers when its state changes.

Observer

The Observer pattern sets up an interface with an update method that concrete observers need to adhere to. This ensures that all observers receive updates from the subject in a consistent manner. Concrete observers then implement this interface, enabling them to respond to changes in the subject’s state accordingly.

ConcreteSubject

ConcreteSubjects are particular realisations of the subject concept. They contain the actual state or data that observers are interested in monitoring. When this state undergoes a change, concrete subjects inform their observers. For example, if we consider a weather station as the subject, then individual weather stations located in various places would serve as concrete subjects.

ConcreteObserver

Concrete Observers implement the observer interface. They enlist with a specific subject and respond when alerted to a state alteration. When the subject’s state shifts, the update() method of the concrete observer is triggered, enabling it to execute suitable actions. For instance, a weather application on your smartphone serves as a concrete observer that responds to updates from a weather station.

Real-world Example

Imagine you’re a seasoned software architect at a well-known financial company called “CapitalWatch.” Your job involves delivering up-to-the-minute market data to various clients like traders, analysts, and investors. Your main task is to guarantee that whenever there’s a change in market data, all subscribed clients get immediate updates so they can act on the latest information.

Implementation

Step 1: Creating the subject

In this example, the subject is the MarketDataFeed. This component’s primary function is to consistently receive real-time market data and to inform all subscribing clients promptly whenever noteworthy market changes take place.

public class MarketDataFeed
{
   private decimal _currentStockPrice;
   public event EventHandler<decimal> MarketDataChanged;
   public decimal CurrentStockPrice
   {
       get { return _currentStockPrice; }
       set
       {
           _currentStockPrice = value;
           OnMarketDataChanged(_currentStockPrice);
       }
   }
   protected virtual void OnMarketDataChanged(decimal newPrice)
   {
       MarketDataChanged?.Invoke(this, newPrice);
   }
}

Step 2: Creating the observers

Here, we are going to create observers that are going to observe the subject for any change in the stock price and market change. These clients sign up with the MarketDataFeed to get live updates in real-time.

public class Client
{
   public string Name { get; }
   public Client(string name)
   {
       Name = name;
   }
   public void ReceiveMarketData(decimal stockPrice)
   {
       Console.WriteLine($"{Name} received a market data update: Stock price is now ${stockPrice}");
   }
}

Step 3: Subscribing to the Subject

To receive up-to-the-minute updates, CapitalWatch’s financial software enables client registration with the MarketDataFeed. This registration establishes a connection between the client and the data feed observers.

MarketDataFeed marketData = new MarketDataFeed();

Client clientA = new Client("Client A");

Client clientB = new Client("Client B");

marketData.MarketDataChanged += clientA.ReceiveMarketData;

marketData.MarketDataChanged += clientB.ReceiveMarketData;

Subscribing to the MarketDataChanged event ensures that Client A and Client B will receive immediate notifications whenever the market data changes.

Step 4: Sending the Updates

When we update the CurrentStockPrice, all the clients that are subscribed to our subject should get the updates immediately.

marketData.CurrentStockPrice = 150.25;

Upon executing this code, both Client A and Client B will promptly receive market updates:

Client A received a market data update: Stock price is now $150.25
Client B received a market data update: Stock price is now $150.25

Conclusion

The Observer design pattern plays a crucial role in software development by enabling the creation of a flexible one-to-many relationship between objects. Within the framework of this example, it guarantees that all subscribed clients receive instantaneous market data updates, empowering them to make informed financial decisions.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top