Joydip Kanjilal
Contributor

Implementing the Observer design pattern in C#

opinion
Jan 30, 20174 mins
Software Development

The observer design pattern defines one-to-many relationship between objects so that changes to one object can be notified to the other dependent objects

The Observer design pattern falls under the Behavioral design pattern category and is used when you would want to notify change to a number of classes. Behavioral design patterns are those that are used to deal with object collaboration and delegation of responsibilities.

Essentially, the Observer design pattern is used to define how communication between components in an application interact with each other or notify one another by sending messages. In this pattern, the subject maintains a list of the observers and then notifies these observers or the dependents as and when a state change happens. You can add or remove observers at runtime as well.

Applicability

When should you use this design pattern? It’s a good choice when you would like to have a subject that has to be observed by one or more observers. It is a popular design pattern that helps you to implement a publisher/subscriber scenario in which changes to an object’s state can be notified to all the dependent objects or subscribers (in a typical implementation of the publisher / subscriber scenario). In the Observer design pattern, the state changes of an object are communicated to another object sans the need of the objects being tightly coupled with each other.

The MVC (Model View Component) architectural pattern is a classic example of an implementation of the Observer design pattern. The MVC architectural pattern is used to build applications that are loosely coupled, easier to test and maintain. In a typical MVC implementation, the View and the Model are decoupled from each other. While the View represents the Observer, the Model represents your Observable object.

Implementing the Observer design pattern

We have had enough of the concepts – let’s now understand this design pattern with an implementation. First off, we need to know the participating classes or types.

  • Subject: This is represented by a type that is used to define an interface to attach or detach one or more observers
  • ConcreteSubject: This is used to notify observers when there is a change of state
  • Observer: This represents the type that should be notified when in the event of a change
  • ConcreteObserver: This represents the concrete implementation of the observer type

In a typical implementation of the Observer design pattern, you might want to have a Subject type and an Observer type. Here’s a code snippet that illustrates this.

    public abstract class Subject

    {

        protected List<Observer> lstObservers = new List<Observer>();

        protected void Register(Observer observer)

        {

            lstObservers.Add(observer);

        }

        protected void UnRegister(Observer observer)

        {

            lstObservers.Remove(observer);

        }

        protected void UnRegisterAll()

        {

            foreach (Observer observer in lstObservers)

            {

                lstObservers.Remove(observer);

            }

        }

        public abstract void Notify();

    }

public abstract class Observer

    {

        public abstract void Update();

    }

Now, refer to the code snippet given above. The Subject class contains a list of Observer instances and a few methods to add or remove the subscribers, i.e., instances of the Observer class. Note that the Notify method has been declared abstract — the class that would extend the Subject class needs to provide the respective implementation for this method. The Observer class contains just one method — the Update method. I’ve made this implementation as simple as possible.

The BlogPost class extends the Subject class and implements the Notify method which has been declared as abstract in the Subject class.

public class BlogPost: Subject

    {

        public void Attach(Observer observer)

        {

            //You can write your own implementation here or call the base version

            base.Register(observer);

        }

        public void Detach(Observer observer)

        {

            //You can write your own implementation here or call the base version

            base.UnRegister(observer);

        }

        public void DetachAll()

        {

            //You can write your own implementation here or call the base version

            base.UnRegisterAll();

        }

        public override void Notify()

        {

            foreach (Observer observer in lstObservers)

            {

                observer.Update();

            }

        }

    }

The ConcreteObserver class is given below. I leave it to the readers to write their own code in the Update method to send an email notifying that an article has been posted, or, etc.

public class ConcreteObserver : Observer

    {

        public string Email

        {

            get; set;

        }

        public override void Update()

        {

            Console.WriteLine("Inside the Update method...");

        }

    }

You can learn more on the Observer design pattern from this link.

Joydip Kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author