Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Observer Pattern

0.00/5 (No votes)
2 Dec 2009 1  
Observer pattern

This articles was originally at wiki.asp.net but has now been given a new home on CodeProject. Editing rights for this article has been set at Bronze or above, so please go in and edit and update this article to keep it fresh and relevant.

Introduction

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 dependants that the object changed its state and therefore the dependants 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.

Observer using .NET Built in Features

Check this really cool Patterns and Practices article Implementing Observer in .NET.

UML Diagram

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 called
        /// </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 implements the Notify method that notifies every observer when the subject state was changed.
When the state changes, the observer makes 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 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 in the 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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here