Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Observer Pattern (C#)

4.89/5 (40 votes)
8 Jan 2015CPOL4 min read 163.7K  
Implementing Observer Design Pattern in C#

Introduction

This tip presents a very interesting design pattern- the observer design pattern. I wrote this tip on Google blogs but I am porting it at the appropriate place.

Background

The observer design pattern is yet another, one of my favorite design patterns which falls in the category of "behavioral pattern". Going by its name, we can say that observer is something (objects in case of OOPS) which is looking upon (observing) other object(s). Observer pattern is popularly known to be based on "The Hollywood Principle" which says- "Don’t call us, we will call you." Pub-Sub (Publisher-Subscriber) is yet another popular nickname given to Observer pattern.

Based on the "Hollywood principle", we can make a guess that in observer pattern, there is a special Hollywood celebrity object in which all other common objects are interested. In actual terms in the observer pattern - "There are n numbers of observers (objects) which are interested in a special object (called the subject). Explaining one step further- there are various objects (called observers) which are interested in things going on with a special object (called the subject). So they register (or subscribe) themselves to subject (also called publisher). The observers are interested in happening of an event (this event usually happens in the boundary of subject object) whenever this event is raised (by the subject/publisher) the observers are notified (they have subscribed for the happening of this event- Remember?)

Using the Code

Simple concepts can be made complex by writing unnecessary literature about that. Let’s dig into an actual example and code to clear everything about observer pattern. Consider an online electronics store which has a huge inventory and they keep on updating it. The store wants to update all its users/customers whenever any product arrives in the store. Just reading the problem statement, we can fit in Observer pattern for the above problem-How? The online electronic store is going to be the subject. Whenever the subject would have any addition in its inventory, the observers (customers/users) who have subscribed to store notifications would be notified through email. Let’s look at the code straight away to get an idea of how we can implement Observer pattern in C#.

Subject

C#
public class Subject:ISubject
{
  private List<Observer> observers = new List<Observer>();
  private int _int;
  public int Inventory
  {
    get
    {
       return _int;
    }
    set
    {
       // Just to make sure that if there is an increase in inventory then only we are notifying 
          the observers.
          if (value > _int)
             Notify();
          _int = value;
    }
  }
  public void Subscribe(Observer observer)
  {
     observers.Add(observer);
  }

  public void Unsubscribe(Observer observer)
  {
     observers.Remove(observer);
  }

  public void Notify()
  {
     observers.ForEach(x => x.Update());
  }
}

interface ISubject
{
   void Subscribe(Observer observer);
   void Unsubscribe(Observer observer);
   void Notify();
}

The "Subject" maintains a list of "Observers". Since every Subject would have somewhat these methods, I tied those in an interface. The Subscribe-Unsubscribe method are the ones through which the Observers register-unregister themselves to the Subject. The Notify method is the one which has the responsibility of notifying all the Observers.

Let’s look at the code for the Observer class:

C#
public class Observer:IObserver
{
  public string ObserverName { get;private set; }
  public Observer(string name)
  {
    this.ObserverName = name;
  }
  public void Update()
  {
    Console.WriteLine("{0}: A new product has arrived at the
    store",this.ObserverName);
  }
}

interface IObserver
{
  void Update();
}

The Observer class is pretty dumb as to it only has a property (ObserverName) to distinguish one observer from another and it also has an Update method. This is the method which almost every observer class would have. It is a way for the Observer for getting notified that something happened in the Subject and since the Observer is registered for notification, so it is getting notified through this method.

Let’s look at the main method which would complete our code for using the Observer pattern.

C#
static void Main(string[] args)
{
   Subject subject = new Subject();
   // Observer1 takes a subscription to the store
   Observer observer1 = new Observer("Observer 1");
   subject.Subscribe(observer1);
   // Observer2 also subscribes to the store
   subject.Subscribe(new Observer("Observer 2"));
   subject.Inventory++;
   // Observer1 unsubscribes and Observer3 subscribes to notifications.
   subject.Unsubscribe(observer1);
   subject.Subscribe(new Observer("Observer 3"));
   subject.Inventory++;
   Console.ReadLine();
}

This Main method is straightforward. We create an instance of Subject so that we can subscribe/unsubscribe different observers. When the inventory in the Subject changes, we notify the Observers by their Update method (look at the code in Subject class).

Below is the output of the program…

Image 1

If you notice that after the first notification since Observer1 has unsubscribed, it would not get notified, when the inventory changes next time. But since Observer3 has subscribed to the list of Observers, it gets notified when there is an update in the Subject.

Points of Interest

The above code for implementing Observer pattern is very simple. There are more sophisticated ways through which we can implement the Observer pattern. One way of doing that is through delegates and events which are very natural in implementing an Observer pattern (Take a look at my article on Events & Delegates [Events & Delegates], the code written there is the implementation of observer pattern). C# now itself supports Observable classes/framework which can be used for implementing Observer pattern. Maybe, I will revisit Observer pattern in another article to have a look at that framework. Also, we will talk about how Subject & Observer implement pull notification and push notification.

History

  • Version 1 - (06/05/2014)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)