The Observer Pattern





5.00/5 (1 vote)
The Observer pattern
In this edition of pronto patterns, I am going to cover the observer pattern. So let’s get started!
The Official Definition
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependants, called observers, and notifies them automatically of any state changes.
Keyword Alert: Subject & Observers
Real World Two
Subject | Observers | Use Case |
Twitter user | Other twitter users (followers) | User sends a tweet; followers are notified of new tweet. |
YouTube Channel | Subscribers (you & me) |
Channel uploads a new video; subscribers are notified of new video. |
Example Overview
Let’s roll with the YouTube example; it’s an idiom we are all familiar with and is unlikely to disappear before you read this.
A user can create a channel under which that user posts content. You and me stumble upon said channel and realise that this user is deploying golden content that we really don’t want to miss and therefore subscribe pronto!
From now on; when that user (the subject of our interest) publishes content, we the observers get notified. Simple, right.
At the heart of this pattern is an interface; the ISubscriber
interface to be precise. The interface has just a single method definition; Notify
, and looks something like this:
public interface ISubscriber
{
void Notify();
}
Each variant of a subscriber must implement this interface and our example subscribers are no different; say hello to Standard and Admin users.
public class StandardUser : ISubscriber
{
public void Notify();
{
Console.WriteLine("Standard User got notified of a new video");
}
}
public class AdminUser : ISubscriber
{
public void Notify();
{
Console.WriteLine("Admin User got notified of a new video");
}
}
In our example, admins need to be informed when a new video is released so they can check its content for copyrighted material and soundtracks. The standard user needs to be notified so they can hurry along and enjoy the latest content.
Now that we have our Observers (subscribers), we need our YouTube channel and what better to represent our real world object than a class? The YouTubeChannel
class, of course.
public class YouTubeChannel
{
List<ISubscriber> _subscribers;
public YouTubeChannel()
{
_subscribers = new List<ISubscriber>();
}
public void Subscribe(ISubscriber subscriber)
{
_subscribers.Add(subscriber);
}
public void UnSubscribe(ISubscriber subscriber)
{
_subscribers.Remove(subscriber);
}
public void Notify()
{
foreach(ISubscriber subscriber in _subscribers)
{
subscriber.Notify();
}
}
}
Nothing mind-blowing here, so just a quick x-ray.
- A local list of subscribers, typed to the interface of course
- A not-very-interesting constructor that just instantiates our list
- A subscribe method that adds the user to our list of subscribers
- An un-subscribe method that removes the user from our list of subscribers
- A notify method that loops through our list of subscribers calling notify on each. remember that each user implements our
ISubscriber
interface and as such must implement ournotify
method
So we have our YouTube channel (subject) and our channel subscribers (observers). Let’s pull it together in our main
method. Console Applications at the ready people.
static void Main(string[] args)
{
YouTubeChannel goldenContentYouTubeChannel = new YouTubeChannel();
ISubscriber annie = new StandardUser();
ISubscriber rob = new AdminUser();
goldenContentYouTubeChannel.Subscribe(annie);
goldenContentYouTubeChannel.Subscribe(rob);
goldenContentYouTubeChannel.Notify();
goldenContentYouTubeChannel.UnSubscribe(annie);
goldenContentYouTubeChannel.Notify();
}
When we run our application, we get no surprises and the console simply prints what we expect.
Well that’s the Observer pattern… pronto style!
On a side note; you have probably been using the Observer pattern without even realising... need a clue?
Button button1 = new Button();
button1.Click += new EventHandler(Button1_Clicked);