This articles explains the Observer Design Pattern. An observer pattern is the type of behavioral design pattern that defines the architecture of the application when its components interact with each other.
The basic concept of this pattern is to design a system with one component (say a master component) notifying its change in state to other components of the system to be notified that are dependent on any change in the master component.
According to the GoF's patterns, it is defined as "Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically".
This pattern is the same as for events and delegates, in which an event, when fired, notifies the components that are registered to it as delegates.
A real world example
One of the simplest examples that can be considered is the Wordpress site, where users post articles for their blog. An interested reader may not be able to visit a blog regularly to check for a new post. So what this site does is, it allows a user to subscribe to the blogger's posts. So whenever a blogger posts an article, the people who have subscribed to the blogger will learn about the new post by email notifications.
Let's get technical
We will be creating a console based application, with the following four components to run this pattern. Also we will be using the following terminology interchangeably, to discuss it:
Blog Writer: posts the blogs as Publisher
Blog Reader: subscribes for new post notifications as Subscriber
The following are some relevant classes and interfaces:
- INotificationService : An interface with the functions used by the publisher (who would like to receive notification) to manage the subscribers and send them the notifications.
- BlogWriter : A concrete class implemented by the publisher, or you can say a blog writer managing his list of the subscribers and a way to notify his users.
- IBlogReaders : An interface used by the subscribers to receive the notifications
- BlogReaders : A concrete implementation of the preceding interface
We will first define a notification service using INotificationService that will be used by the publisher to add/remove or notify the subscribers. We will have three methods, in other words AddSubscriber, RemoveSubscriber and NotifySubscribers.
Next we will be defining a way for the subscribers to receiver their notifications, in other words IBlogReaders. So our code will look like the following:
Next, our publisher will be implementing the service for notification, or you can say, manage his subscribers, as per his requirements. So our code will be as follows:
As we can see here, the notification service adds the type of the subscribers that are implementing the interface IBlogReaders, which means, it is adding subscribers, who have a way of receiving notifications through this interface.
So between a publisher and the subscriber, the INotificationService and IBlogReaders act as the intermediates or the co-ordinators. INotificationService from the publisher side and IBlogReader from the subscriber side. The NotifyReaders method in the code above does that.
Finally, our subscriber will be implementing the IBlogReader, to manage themselves or perform what they would like to, whenever they receive any notifications. So our code will be as follows:
Here, we will be simply writing the output to the console.
So the basic setup is done. Now its time for the blog writer to write posts and publish it. So our code will be like the following:
So we add the subscribers to the list and call the NotifyReaders method, with the notification message. So calling this method results in a call to the NotificationReceived method of the subscribers (see the image previous to the precedingone). In a single method call to NotifyReaders, all the subscribers are notified. Run the application and see the output.
So, we could have remove any of the subscribers from the list as needed and the subscriber will no longer receive the notification.
So this was about the concept of the Observer pattern.