Observer Pattern

August 4, 2008

2 comments

Observer Pattern


The post will describe why and how to use the observer design pattern and will
have a C# example of how to implement the pattern.
You can read my previous posts about design patterns here:
Structural patterns
Decorator pattern 
Proxy pattern
Facade pattern
Adapter pattern
Composite pattern
Bridge pattern
Flyweight pattern

Creational patterns
Singleton pattern
Abstract Factory pattern
Prototype pattern
Factory Method pattern
Builder pattern

Behavioral Patterns
Strategy pattern
Iterator pattern 
Template method pattern
Command pattern
Chain of responsibility pattern 
Mediator pattern
Memento pattern
State pattern
Visitor pattern

Observer Pattern    
The observer design pattern defines a one to many dependency between
an object and its dependents. The dependency is created in order to inform
the dependents that the object changed its state and therefore the dependents
can react to the change. A very good example of such behavior is the blogging
systems were subscribers are notified whenever a blogger published a new post.
Another real world example can be the MVC architecture pattern which uses the 
pattern.
 
Use Cases for the Observer Pattern

You should use the pattern in the following cases:



  • You have a publisher/subscriber model.

  • Objects need to be notified of a change in another objects.

  • You need that the object that notify its state change would not
    know about its subscribers.

UML Diagram     
Observer Pattern      


Example in C#
The following code is an example of how to implement the pattern:



    #region Subject


    public abstract class Subject


    {


        #region Members


        private List<IObserver> _observers;


        #endregion


        #region Ctor


        /// <summary>


        /// Construct a new subject object


        /// </summary>


        public Subject()


        {


            _observers = new List<IObserver>();


        }


        #endregion


        #region Methods


        /// <summary>


        /// Attaches a new observer to the subject


        /// </summary>


        /// <param name=”observer”>The observer to attach</param>


        public void Attach(IObserver observer)


        {


            _observers.Add(observer);


        }


        /// <summary>


        /// Detaches an observer from the subject


        /// </summary>


        /// <param name=”observer”>The observer to detach</param>


        public void Detach(IObserver observer)


        {


            _observers.Remove(observer);


        }


        /// <summary>


        /// Notify all the observers about the change in the


        /// subject’s state


        /// </summary>


        public void Notify()


        {


            foreach (IObserver observer in _observers)


            {


                observer.Update();


            }


        }


        #endregion


    }


    #endregion


    #region Concrete Subject


    public class ConcreteSubject<T> : Subject


    {


        #region Properties


        /// <summary>


        /// The state of the subject


        /// </summary>


        public T SubjectState { get; set; }


        #endregion


    }


    #endregion


    #region Observer


    public interface IObserver


    {


        void Update();


    }


    #endregion


    #region Concrete Observer


    public class ConcreteObserver<T> : IObserver


    {


        #region Properties


        /// <summary>


        /// The subject the observer holds


        /// </summary>


        public ConcreteSubject<T> Subject { get; set; }


        private T _observerState;


        #endregion


        #region Ctor


        /// <summary>


        /// Construct a new concrete observer with the given


        /// subject


        /// </summary>


        /// <param name=”subject”>The given subject</param>


        public ConcreteObserver(ConcreteSubject<T> subject)


        {


            Subject = subject;


        }


        #endregion


        #region IObserver Members


        /// <summary>


        /// Make an update to the observer state whenever the


        /// method is callled


        /// </summary>


        public void Update()


        {


            _observerState = Subject.SubjectState;


            Console.WriteLine(“The new state of the observer:{0}”,


                _observerState.ToString());


        }


        #endregion


    }


    #endregion


The example is simple to follow. We have an IObserver interface and a
Subject abstract class. The observers are registered in the subject with the
Attach method and also can be detached. The subject implement the Notify
method that notifies every observer when the subject state was changed.
When the state changes the observer make an update which is the main
method of the IObserver interface.


The following code is an example scenario of how to run the pattern in
console application:



   ConcreteSubject<string> subject =


      new ConcreteSubject<string>();


   subject.Attach(new ConcreteObserver<string>(subject));


   subject.Attach(new ConcreteObserver<string>(subject));


   subject.SubjectState = “Hello World”;


   subject.Notify();


   Console.Read();


Summary
To sum up the post, the observer pattern is widely used and it is very helpful.
You can see the uses of the pattern in the MVC framework for example or even
here in Israel Microsoft blogs when you subscribe to a blog in order to be notified
of new blogger posts.
The next post in the design patterns series will be the last pattern post and
it will include the interpreter pattern.


Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

2 comments

  1. CarlAugust 4, 2008 ב 12:46

    Thank you, very good article. Something they uses 1h to explain in school I now learned here by 2mins :)

    Reply