Pages

I've migrated my blog

Thanks for visiting my blog. I am no longer maintaining this and I've migrated the blog to my personal domain . If you would like to follow my blog kindly use my new RSS feed

Wednesday, July 13, 2011

Observer Pattern using Delegates V/s Observer Pattern using Events and Delegates

Most of the articles and texts in C# demonstrate the observer pattern using events and delegates. When going through one such text, a thought come across my mind. Why we are going for events when we can easily achieve the multicasting using Delegates alone. After some R&D, I found it out why and hence this blog post.
I am going to explain this “why” using a Weather Station example. To keep things simple, the Weather Station that we are going to see will keep track of only the temperature. Whenever the temperature changes, it simplify notifies its subscribers with the new temperature. Flash News is one of the subscribers which show the temperature in flash news. News Feed, another subscriber which adds the temperature information to the news feed. Fine, enough theory! It’s time to see the code.
Here is the implementation of Observer Pattern using Delegates alone.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegatesAndEvents
{
    class WeatherStation
    {
        private int _temperature;
        public TemperatureReporter Reporter { get; set; }
        public int Temperature
        {
            get { return _temperature; }
            set
            {
                if (Reporter != null)
                {
                    Reporter(value);
                }
                _tempearture = value;
            }
        }
    }

    class NewsFeed
    {
        WeatherStation weatherStation;

        public void AddTemperatureInfoToFeed(int temperature)
        {
            Console.WriteLine("News Feed: New temperature " + 
                                temperature + " added to feed.");
        }

        public NewsFeed(WeatherStation weatherStation)
        {            
            this.weatherStation = weatherStation;
            weatherStation.Reporter += AddTemperatureInfoToFeed;
        }
    }

    class FlashNews
    {
        WeatherStation weatherStation;

        public void ShowTemperatureInfoInFlashNews(int temperature)
        {
            Console.WriteLine("Flash News: New temperature is " + temperature + ".");
        }

        public FlashNews(WeatherStation weatherStation)
        {            
            this.weatherStation = weatherStation;
            weatherStation.Reporter += ShowTemperatureInfoInFlashNews;
        }
    
    }
}
        
The Main Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegatesAndEvents
{
    public delegate void TemperatureReporter(int tempearture);

    class Program
    {
        static void Main(string[] args)
        {   
            // Observer Pattern Using Delegates                     
            WeatherStation weatherStation = new WeatherStation();
            FlashNews flashNews = new FlashNews(weatherStation);
            NewsFeed newsFeed = new NewsFeed(weatherStation);        
            weatherStation.Temperature = 30;
            weatherStation.Temperature = 15;
            weatherStation.Temperature = 45;
        }
    }
}
The output

Hurrah! It’s working as expected. Both subscribers are get notified. We can implement the observer pattern using delegates alone. Stop for a minute and go through the code, is the implementation robust? Kudos if you are able to find the shortcomings of this implementation. If not continue reading.
Think of a world where everyone is good. There is no need of police, no need of court either. But it is not the case. You may wonder why I am mentioning this here. This analogy holds true for the objective of this blog post too. There is no need of using events in the c# programming world if all the subscribers are good. Miserably, here also it is not the case. Hence we are going for events instead of using delegates alone.
Drawbacks of using delegates alone:
  • A subscriber can replace other subscribers by reassigning the delegate
  • A subscriber can clear all other subscribers also (by setting the delegate to null).
  • A subscriber can broadcast to other subscribers by invoking the delegate
Clearly all the above 3 drawbacks violates the Observer Pattern.
Here is our evil subscriber code implementation.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegatesAndEvents
{
    class EvilSubscriber
    {
        WeatherStation weatherStation;

        public void EvilMessage(int temperature)
        {
            Console.WriteLine("The temperature is " + (temperature * 100));
        }

        public EvilSubscriber(WeatherStation weatherStation)
        {
            this.weatherStation = weatherStation;
            
            // Broadcast to all the subscriber
            weatherStation.Reporter(60);

            // Reassign the subscriber
            weatherStation.Reporter = EvilMessage;

            // Replace all the subscribers
            weatherStation.Reporter = null;

        }
    }
}
    
Hope now you understand the need of a better implementation of observer pattern. Here comes the salvage. Event! Use event along with delegates. With event in place, compiler will not allow the evil subscriber to get compiled.
Robust implementation of Weather Station using events.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DelegatesAndEvents
{    
    class WeatherStation2
    {
        private int _tempearture;
        public event TemperatureReporter Reporter;
        public int Temperature
        {
            get { return _tempearture; }
            set
            {
                if (Reporter != null)
                {
                    Reporter(value);
                }
                _tempearture = value;
            }
        }
    }

    class NewsFeed2
    {
        WeatherStation2 weatherStation;

        public void AddTemperatureInfoToFeed(int temperature)
        {
            Console.WriteLine("News Feed2: New temperature " + temperature + " added to feed.");
        }

        public NewsFeed2(WeatherStation2 weatherStation)
        {
            this.weatherStation = weatherStation;
            weatherStation.Reporter += AddTemperatureInfoToFeed;
        }
    }

    class FlashNews2
    {
        WeatherStation2 weatherStation;

        public void ShowTemperatureInfoInFlashNews(int temperature)
        {
            Console.WriteLine("Flash News2: New temperature is " + temperature + ".");
        }

        public FlashNews2(WeatherStation2 weatherStation)
        {
            this.weatherStation = weatherStation;
            weatherStation.Reporter += ShowTemperatureInfoInFlashNews;            
        }
    }
}
    
The unfortunate evil subscriber which failed to compile
    class EvilSubscriber2
        {
            WeatherStation2 weatherStation;

            public void EvilMessage(int temperature)
            {
                Console.WriteLine("The temperature is " + (temperature * 100));
            }

            public EvilSubscriber2(WeatherStation2 weatherStation)
            {
                this.weatherStation = weatherStation;

                // Broadcast to all the subscriber
                weatherStation.Reporter(60); // Compiler Error

                // Reassign the subscriber
                weatherStation.Reporter = EvilMessage; // Compiler Error

                // Replace all the subscribers 
                weatherStation.Reporter = null; // Compiler Error  

            }
        }
    
Summary
Critique what you read and analyze.You can download the source code from here

2 comments:

  1. Hi! I understand this is kind of off-topic but I had to ask. Does managing a well-established blog like yours require a lot of work? I am completely new to operating a blog however I do write in my diary daily. I’d like to start a blog so I can share my personal experience and views online. Please let me know if you have any kind of suggestions or tips for new aspiring blog owners. Thankyou!

    What your stating is absolutely genuine. I know that everyone ought to say the identical factor, but I just feel that you set it in a way that absolutely everyone can realize. I also adore the photographs you set in here. They fit so nicely with what youre hoping to say. Im guaranteed youll attain so numerous people today with what youve got to say.

    These moles may possibly be irregular in size and color and that is what can make them this type of wellness danger. When you have been born with this particular problem you might also be more likely to develop Melanoma and so you might have to get the required precautions with regards to protecting your pores and skin and your well being.

    This is such a great post, and was thinking much the same myself. It’s certainly an opinion I agree with.

    Enjoyed this article. I believe that the writer took an rationale perspective and made some pivotale ideas.

    Aw, it was an extremely good post. In notion I must place in writing such as this moreover – spending time and actual effort to make a really good article… but so what can I say… I procrastinate alot and no means apparently go completed.

    You need to experience a tournament for just one of the most effective blogs on the web. I’ll recommend this page!

    Thank you for yet another great informative article, I’m a loyal reader to this blog and I can’t stress enough how much valuable information I’ve learned from reading your content. I really appreciate all the hard work you put into this great site.

    When I originally commented I clicked the -Notify me when new comments are added- checkbox and now when a comment is added I buy four emails concentrating on the same comment. Perhaps there is in any manner you can get rid of me from that service? Thanks!

    ReplyDelete