Observer Design Pattern allows you to have a publisher-subscriber framework where a change to a publisher will notify all of its subscribers automatically. The subscribers are registered to the publisher so that when a change occurs in the publisher all of the subscribers are notified. The publishers and the subscribers are decoupled through the use of interfaces so that the development of each can vary independently.

The first are the subjects. They are the publishers. When a change occurs to a subject it should notify all of its subscribers.

The second are the observers. They are the subscribers. They simply listen to the changes in the subjects.

The subjects are the publishers and the observers are the subscribers. It's just a different terminology. Below is the UML of the Observer Design Pattern, the left part are the subjects, and the right part are the observers:

The ISubject is the interface that all publishers implement and has the following properties and methods:

observers -- List of observers that listen to the changes in the subject

Attach(IObserver) -- Adds an observer to listen to changes in the subject

Detach(IObserver) -- Remove an observer from listening changes in the subject

Notify() -- Send updates to all the observers that subscribed to it

The ConcreteSubject is the publisher class and it implements the ISubject interface. Besides the implementation of the ISubject interface it also has the subjectState variable:

subjectState -- the variable that represents the state of the subject

The IObserver is the interface that all subscribers implement and has the Update method:

Update() -- update the subscriber and is called by the subject (publisher)

The ConcreteObserver is the subscriber class and it implements the IObserver interface. Below are its variables and methods:

observerState -- the variable that represents the state of the observer

Update() -- update the state of the observer. Notice that the method simply assigns the observerState variable from the subject's state. Therefore when a change to the subject's state occurs, the observer's state will become the same as the subject's state.

Notice in the Update method of the ConcreteObserver we assign the observerState variable as the subject's state and we only have one observerState variable. This means that the observer pattern is a one-to-many relationship, where one subject can have many observers listening to the subject's change but not vice versa.

A comparison between the mediator pattern and the observer pattern shows some similarities and some clear differences. Both patterns facilitates the communication between objects, and both decouples the link between the sender and the receiver. The main difference is that in the mediator pattern there is the notion of the participants and they communicate with each other using the mediator as a central hub, whereas in the observer pattern there is a clear distinction between the sender and the receiver, and the receiver merely listens to the changes in the sender.

While there are many different ways to implement the observer pattern, such as using delegates and events or the IObserver<T>, the concepts are all the same. That is, the observers are registered to listen to the changes in the subject and are notified when the subject changes. For the purpose of demonstrating the concept of the observer pattern we will not dig into the technicalities of the multiple ways to implement the pattern, but simply show how the observer pattern works by demonstrating the concept.

Below are the implementation code and the output of the Observer Design Pattern. Notice that a change to the subject automatically updates all of its observers:

What I like about this series is that it presents the patterns using C# code snippets and uses very concrete and easy to understand examples with screenshots of the output. It's also free and presented in a single collection, as opposed to many of the other authors that only cover a couple of the patterns.