Dot Net For All

Simple observer pattern using C# delegate

In this article I will discuss about the observer pattern in C# with simple code example. I will use the publisher subscriber mechanism of the delegates to implement the observer pattern.

What is Observer Pattern ?

Before starting the discussion about the observer pattern let me brief about the pattern. In this pattern when the state of one object(observer) is changed that changed is propagated to all the dependent objects.

In this article I will use delegates to implement this pattern. I have discussed about delegates here.

UML Diagram

Please have a look at the below figure for the UML diagram.

Publisher: This is the class which keeps the list of all the subscribers with the help of the delegate instance.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">delegate</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">Notifier</span>(<span style="color: #333399; font-weight: bold">string</span> message); 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">class</span> <span style="color: #BB0066; font-weight: bold">Publisher</span> { 
Notifier notifier; 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">Attach</span>(Notifier notifier) {
 <span style="color: #008800; font-weight: bold">this</span>.notifier += notifier; 
} 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">Remove</span>(Notifier notifier) {
 <span style="color: #008800; font-weight: bold">this</span>.notifier -= notifier; 
} 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">SendMessgae</span>(<span style="color: #333399; font-weight: bold">string</span> message) {
 <span style="color: #008800; font-weight: bold">if</span> (<span style="color: #008800; font-weight: bold">this</span>.notifier != <span style="color: #008800; font-weight: bold">null</span>) 
     notifier(message); 
} 
}
</pre></div>

We can safely use the delegate here as we know that delegate class contains invocation list and we can attach and detach the methods to the invocation list as shown in the Attach and Remove methods.

Observer :

Observer is the class which has the instance of the Publisher class and whenever any change is happened in the instance of this class. The publisher is notified which in turn notifies all the subscribers. The code for Observer is as following.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">class</span> <span style="color: #BB0066; font-weight: bold">ArticleServiceObserver</span> {
 <span style="color: #008800; font-weight: bold">private</span> Publisher publish; 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #0066BB; font-weight: bold">ArticleServiceObserver</span>(Publisher publish) { 
 <span style="color: #008800; font-weight: bold">this</span>.publish = publish; 
} 
<span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">AddNewArticle</span>(<span style="color: #333399; font-weight: bold">string</span> articleName) { 
 publish.SendMessgae(<span style="background-color: #fff0f0">&quot;New Article Available: &quot;</span> + articleName); 
} 
}
</pre></div>

Subscriber : 

This is the class which is subscribed to the publisher to receive notifications. In our case Person class is the subscriber, where the instances of this class will receive the notifications for the newly published articles.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">class</span> <span style="color: #BB0066; font-weight: bold">Person</span> {
 <span style="color: #008800; font-weight: bold">private</span> <span style="color: #333399; font-weight: bold">string</span> name; 
 <span style="color: #008800; font-weight: bold">public</span> <span style="color: #0066BB; font-weight: bold">Person</span>(<span style="color: #333399; font-weight: bold">string</span> name) 
 { 
   <span style="color: #008800; font-weight: bold">this</span>.name = name; 
 } 
 <span style="color: #008800; font-weight: bold">public</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">GotArticle</span>(<span style="color: #333399; font-weight: bold">string</span> message) 
 { 
   Console.WriteLine(<span style="color: #333399; font-weight: bold">string</span>.Format(<span style="background-color: #fff0f0">&quot;Hello {0}, {1}&quot;</span>, name, message)); 
 } 
}
</pre></div>

Now its time to see our observer pattern in use.

<!-- HTML generated using hilite.me --><div style="background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">static</span> <span style="color: #008800; font-weight: bold">void</span> <span style="color: #0066BB; font-weight: bold">Main</span>(<span style="color: #333399; font-weight: bold">string</span>[] args) 
{ 
  Publisher pub = <span style="color: #008800; font-weight: bold">new</span> Publisher(); 
  Person per1 = <span style="color: #008800; font-weight: bold">new</span> Person(<span style="background-color: #fff0f0">&quot;Michale&quot;</span>); 
  pub.Attach(per1.GotArticle); 
  Person per2 = <span style="color: #008800; font-weight: bold">new</span> Person(<span style="background-color: #fff0f0">&quot;Jordon&quot;</span>); 
  pub.Attach(per2.GotArticle); 
  ArticleServiceObserver observer = <span style="color: #008800; font-weight: bold">new</span> ArticleServiceObserver(pub); 
  observer.AddNewArticle(<span style="background-color: #fff0f0">&quot;Delegates in C#&quot;</span>); 
  pub.Remove(per2.GotArticle); 
  observer.AddNewArticle(<span style="background-color: #fff0f0">&quot;Observer pattern&quot;</span>); 
  Console.Read(); 
}
</pre></div>

In the above code we can see that I have created two persons and subscribed the GotArticle() method of each instance to the publisher. Now when “Delegates in C#” is published both the person will receive the notification. Now suppose if one of the person wants to unsubscribe, in this “Jordon” has done it. When the second article is published only “Michale” will receive the notification as shown in the figure below.


Conclusion

In this article we have seen how easily we can implement observer pattern using delegates in C#.

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview