An observer pattern (also called a publisher subscriber pattern) consists of a subject and many observers. The subject notifies the observer in case of a change in state. The image below shows a real life scenario that imitates the observer pattern. Here the recruiter of a company is the subject and the job hunters are the observers.
The Observers (John and Steve's teams) should be able to take the appropriate action when notified.
using System;
using System.Collections.Generic;
using System.Threading;
public interface INotificationObserver
{
void OnServerDown();
}
public interface INotificationService
{
void AddSubScriber(INotificationObserver
obs);
void RemoveSubScriber(INotificationObserver
obs);
void NotifyObserver();
}
internal class Playground
{
//This is the entry point for the application
private static void Main(string[]
args)
{
var ns = new NotificationService();
var Jo = new JohnsObserver(ns);
var So = new StevesObserver(ns);
while (true)
{
if (PingSqlServer() == false)
{
//When SQL server is down notify observer
Console.WriteLine("Server down!");
ns.NotifyObserver();
}
else
{
Console.WriteLine("All is good");
}
Thread.Sleep(1000);
}
}
private static bool PingSqlServer()
{
//All this method does is randomly return a false
var random = new Random();
int i =
random.Next(1, 30);
if (i > 20)
{
return false;
}
else
{
return true;
}
}
}
public class NotificationService : INotificationService
{
private readonly List<INotificationObserver>
_observers;
public NotificationService()
{
_observers = new List<INotificationObserver>();
}
public void
AddSubScriber(INotificationObserver obs)
{
_observers.Add(obs);
}
public void RemoveSubScriber(INotificationObserver obs)
{
_observers.Remove(obs);
}
public void
NotifyObserver()
{
foreach (INotificationObserver
Obs in _observers)
{
Obs.OnServerDown();
}
}
}
public class JohnsObserver : INotificationObserver
{
private readonly INotificationService _localRefToNotiServ;
public JohnsObserver(INotificationService
notiServ)
{
_localRefToNotiServ = notiServ;
_localRefToNotiServ.AddSubScriber(this);
}
public void
OnServerDown()
{
//Send email to John
Console.WriteLine("An
email was sent to John");
}
public void Unlist()
{
_localRefToNotiServ.RemoveSubScriber(this);
}
}
public class StevesObserver : INotificationObserver
{
private readonly INotificationService _localRefToNotiServ;
public StevesObserver(INotificationService
notiServ)
{
_localRefToNotiServ = notiServ;
_localRefToNotiServ.AddSubScriber(this);
}
public void
OnServerDown()
{
//Send text message to Steve
Console.WriteLine("A
text was sent to Steve");
}
public void Unlist()
{
_localRefToNotiServ.RemoveSubScriber(this);
}
}
What is shown above is a push mechanism where in the Subject pushes the update to the Observer. Observer Pattern can also be implemented with a pull mechanism where in the the Observer initiates the Notify mechanism from the Subject.