In Focus

Observer Design Pattern Using C#

In this article, we will understand what Observer Pattern is and when we actually need to use it, along with a practical example and real life use case.

This pattern falls under the category of behavioral pattern. As the name suggests, it is based on the principle where one object observes another object.

So, in simple words, this pattern defines a one-to-many relationship between subject and observer objects so that if the subject changes its state, then all of the dependent observer objects will be notified of the change.

Let’s understand it in more details using the UML diagram, as shown below.

Observer Design Pattern Using C#
Image source: Wikipedia

For example

 
Consider a technical author like we have in C# Corner, who writes blogs, articles etc. So, if someone likes reading articles from a specific author, one can follow/subscribe the author for future articles. This is a real-life scenario of the Observer pattern.

In this case, all the subscribers who want to subscribe to the author are Observer Objects and the author is a Subject.

Now, let’s dive into the actual code to see how it works.

This is the interface which will be implemented by the subject.

  1. public interface ISubject {  
  2.     void registerObserver(Observer observer);  
  3.     void unregisterObserver(Observer observer);  
  4.     void notifyObservers();  
  5. }  

This is the Subject class and as per our example mentioned above, the author will be the Subject. So here, we are assuming that the author has already written 1 article and those who will like the article can subscribe or unsubscribe (if they have already subscribed) accordingly.

Now, whenever the subject changes its state, all of its observers will be notified.

  1. public class Subject: ISubject {  
  2.     private List < Observer > Observers = new List < Observer > ();  
  3.     private int articlesCount = 1;  
  4.     public int Articles {  
  5.         get {  
  6.             return articlesCount;  
  7.         }  
  8.         set {  
  9.             if (value > articlesCount) {  
  10.                 articlesCount++;  
  11.                 notifyObservers();  
  12.             }  
  13.         }  
  14.     }  
  15.     public void registerObserver(Observer observer) {  
  16.         Observers.Add(observer);  
  17.     }  
  18.     public void unregisterObserver(Observer observer) {  
  19.         Observers.Remove(observer);  
  20.     }  
  21.     public void notifyObservers() {  
  22.         foreach(var observer in Observers) {  
  23.             observer.Update();  
  24.         }  
  25.     }  

This is the interface which will be implemented by all the Observer objects. As per our example, all the subscribers/followers for the author will be the Observer objects.

  1. public interface IObserver {  
  2.     void Update();  
  3. }  

This is the Observer class which can be used to create different observers.

  1. public class Observer: IObserver {  
  2.     public string ObserverName;  
  3.     public Observer(string name) {  
  4.         ObserverName = name;  
  5.     }  
  6.     public void Update() {  
  7.         //Observer can update his system accordingly  
  8.         Console.WriteLine("Hello " + ObserverName + ", a new article has been published by the author.");  
  9.     }  
  10. }  
Finally, this is the main method which can be used for running this program.
  1. void Main() {  
  2.     var subject = new Subject();  
  3.     var observerA = new Observer("Observer A");  
  4.     var observerB = new Observer("Observer B");  
  5.     var observerC = new Observer("Observer C");  
  6.     Console.WriteLine("Intially suppose Subject has already written total " + subject.Articles + " article");  
  7.     Console.WriteLine("\n*******************************************************************************\n");  
  8.     Console.WriteLine("Registering observers A and B for future articles...............");  
  9.     subject.registerObserver(observerA);  
  10.     subject.registerObserver(observerB);  
  11.     Console.WriteLine("New article published by Subject,so now observers A and B will be notified....\n");  
  12.     subject.Articles++;  
  13.     Console.WriteLine("---------------------------------------------------------------------------\n");  
  14.     Console.WriteLine("Registering observer C for future articles and unregistering observer B from the future articles...............");  
  15.     subject.registerObserver(observerC);  
  16.     subject.unregisterObserver(observerB);  
  17.     Console.WriteLine("New article published by Subject,so now observers A and C will be notified....\n");  
  18.     subject.Articles++;  
  19.     Console.WriteLine("\n*******************************************************************************\n");  
  20.     Console.WriteLine("Finally Subject has written total " + subject.Articles + " article \n");  
  21. }  

OUTPUT

 
Observer Design Pattern Using C#
 

When should we use this

We should use it when multiple objects are dependent on the state of one object.

Some common Use Cases

  • Following someone on Instagram/Twitter and other such platforms.
  • App users gets notified for the updates.
  • Email Subscriptions and many more.

I hope you find this article helpful. Stay tuned for more … Cheers!!