Sunday, 24 March 2013

Posted by Prasad KM | 01:24 Categories:

Observer Design Pattern in C#




The Observer design pattern is a relationship between objects so that when one changes its state, all the others are notified accordingly. In other words, it defines that an object must be able to notify other objects without making assumptions about what these objects are.
Observer design pattern is quite useful when a change to one object requires changing others but, you don't know how many objects need to be changed.

Using Observer Design Pattern in Blog Subscriber Example

In this example, I have used two other behavioral patterns which are Iterator Design Pattern in C# and Facade Design Pattern in C#. The simplest way to understand observer pattern is to look at blogs, which are websites where people write about different topics. Take an example of one blog where so many users have subscribed themselves for any new post. As we all know, bloggers don't always post regularly so it would be great for bloggers to alert all subscribers whenever the blogger posts a new topic.
  • Blog is a class which deals with the new blog post and also with the blog subscribers.
  • BlogPost is a class which deals with the posting of a new article.
  • Subscribers are the users who have subscribed themselves for alerts of new articles.
  • Facade deals them in a simpler way and gives you operations like PublishSinglePost() orPublishMultiPost(), etc.
  • Subject class whose instances independently change their state and it notifies to all the subscribers.
  • Run method loops through all of the Subscribers calling their Update methods to notify them about post. It also contains methods for attaching and detaching functions with event.
Imagine using Iterator Design Pattern in C# we have a list of subscribers as follows:
class Subscriber
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public Subscriber(string name, string email)
        {
            this.Name = name;
            this.Email = email;
        }
    }

    class BlogSubscribers : IEnumerable
    {
        Subscriber[] Arrays = { new Subscriber("user1", firstEmail@gmail.com), 
				new Subscriber("user2", "2ndEmail@gmail.com") };

        public IEnumerator GetEnumerator()
        {
            foreach (Subscriber element in Arrays)
                yield return element;
        }
    } 
For more details related to the above code and Iterator design pattern, read my article on Iterator Design Pattern in C#.
Subject class instances independently change their state and it notifies to all the subscribers. It defines aDictionary object to store the subscribers name and their callback functions.
public delegate void Callback(String subscriber);
    class Subject
    {
        //Declaring delegate 
        Dictionary<string, Callback> Notify = new Dictionary<string, Callback>();
        //Declaring Event 
        // List of Users as IEnumerable
        BlogSubscribers blogSubscribers = new BlogSubscribers();

        /// <summary>
        /// Attaching the events
        /// </summary>
        /// <param name="subscriber">its the name of user or email address</param>
        /// <param name="Update">A method to attach </param>
        public void Attach(string subscriber, Callback Update)
        {
            if (!Notify.ContainsKey(subscriber))
            {
                Notify[subscriber] = delegate { };
            }

            Notify[subscriber] += Update;
        }
        /// <summary>
        /// To Detach method for specific user
        /// </summary>
        /// <param name="subscriber">its the name of user or email address</param>
        /// <param name="Update">A method to attach</param>
        public void Detach(string subscriber, Callback Update)
        {

            Notify[subscriber] -= Update;
        }
        /// <summary>
        /// Loop through all users to notify for anychange
        /// </summary>
        public void Run()
        {
            foreach (Subscriber subscriber in blogSubscribers)
            {
                string message = string.Format(" To {0}<{1}> ", 
				subscriber.Name, subscriber.Email);
                Notify[subscriber.Name](message);
            }
        }
    }
An interface for IObserver specifies how they should be updated. A BlogSpot for posting new articles and observers as a BlogObserver:
interface IObserver
    {
        void Update(string message);
    }
    class BlogPost
    {
        public string PostName { get; set; }

    }
    class BlogObserver : IObserver
    {
        //name of the posting

        // Implementing through IOC Inversion of control 
        Subject subject;
        List<BlogPost> ListOfBlogNewPosts = new List<BlogPost>();
        public BlogObserver(Subject subject)
        {
            this.subject = subject;
            subject.Attach("user1", Update);
            subject.Attach("user2", Update);

        }
        public void AddPost(BlogPost blogPost)
        {
            ListOfBlogNewPosts.Add(blogPost);
        }

        public void Update(string message)
        {
            foreach (BlogPost blogPost in ListOfBlogNewPosts)
            {
                Console.WriteLine
		("--------------------- New Posting ---------------------");
                Console.WriteLine(" {0} for Post {1}", message, blogPost.PostName);
                Console.WriteLine();
            }
        }
        public void DetachFromPost(string subscriber)
        {
            subject.Detach(subscriber, Update);
        }
    }
I have used Facade Design Pattern in C# to make an easy interface for these different sub systems.
 public class BlogFacade
    {
        public static void PublishMultiPost()
        {
            Subject subject = new Subject();
            BlogPost Ps3 = new BlogPost();
            Ps3.PostName = "PS3";
            BlogPost Xbox = new BlogPost();
            Xbox.PostName = "Xbox";
            BlogObserver salmanBlog = new BlogObserver(subject);
            salmanBlog.AddPost(Ps3);
            salmanBlog.AddPost(Xbox);
            //let's try to detach users2 from the subscriber list for posting xbox
            //salmanBlog.DetachFromPost("user2");
            subject.Run();
        }
        public static void PublishSinglePost()
        {
            Subject subject = new Subject();
            BlogPost Xbox = new BlogPost();
            Xbox.PostName = "Xbox";
            BlogObserver salmanBlog = new BlogObserver(subject);
            salmanBlog.AddPost(Xbox);
            subject.Run();
        }
    } 
For more details regarding facade pattern, visit Facade Design Pattern in C#.
static void Main()
    {
        //BlogFacade.PublishSinglePost();
        BlogFacade.PublishMultiPost();
    }  

Output

So if you run facade operation BlogFacade.PublishMultiPost(); by commenting//salmanBlog.DetachFromPost("user2"); then output will be:
image1.png
and if you uncomment this salmanBlog.DetachFromPost("user2"); and runBlogFacade.PublishMultiPost(); the output will be:
image2.png
because we have unsubscribed user2 from the list. So that is our blog on Observer pattern if for any new post or change in post, all the others are notified accordingly.

0 comments:

  • RSS
  • Delicious
  • Digg
  • Facebook
  • Twitter
  • Linkedin
  • Youtube