Welcome to the Design Pattern For Beginners article series. In this article series we are discussing various design patterns of software development. This is the 10th presentation and if you are new to this series then I suggest you go through all previous articles.
Let's discuss the importance of the Observer Design Pattern and when it needs to be implemented.
Why observer pattern?
As the name suggests, it's something related to observation. The question is, who is the observer? The observers are nothing but various systems.
The concept is, one or more systems will be the observer simultaneously and if necessary they can start their action. It's like a bodyguard. Right?
Let's talk about a notification system where the user can send notifications in various ways. They may use SMS notification or Mail Notification or Event Log.
Now, all the notification systems will be alive continuosly, and if needed we can use any one of them, or more than one simultaneously. So , if we draw the conclusion, observer pattern is fit that situation where we choose and use systems at run time. Whereas all systems will alive continuosly. Let's try to implement that in code.
Create various notification classes
We are interested in implementing a uniform naming convention. For that we will implement all notification classes from the INotifyObserver Interface. Each notification class will be implementing a Notify() method.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ObserverPattern
{
interface INotifyObserver
{
void Notify();
}
class MailNotify : INotifyObserver
{
public void Notify()
{
Console.WriteLine("Notify through Mail");
}
}
class EventNotify : INotifyObserver
{
public void Notify()
{
Console.WriteLine("Notify through Event");
}
}
class SMSNotify : INotifyObserver
{
public void Notify()
{
Console.WriteLine("Notify through SMS");
}
}
}
Create notifier class
This is a very interesting and important part of the Observer Design Pattern. We can say clsNotifier (see the following code) is our control room. From here we will control which kind of notification will execute.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ObserverPattern
{
class clsNotifier
{
public ArrayList ALNotify = new ArrayList();
/// <summary>
/// Add object of notification System
/// </summary>
/// <param name="obj">Object is notification class</param>
public void AddService(INotifyObserver obj)
{
ALNotify.Add(obj);
}
/// <summary>
/// Remove object of notification System
/// </summary>
/// <param name="obj">Object of notification Calss</param>
public void RemoveService(INotifyObserver obj)
{
ALNotify.Remove(obj);
}
public void ExecuteNotifier()
{
foreach (INotifyObserver O in ALNotify)
{
//Call all notification System
O.Notify();
}
}
}
}
AddService() and RemoveService() are two functions by which we can add an object of various notification classes and ExecuteNotifier() will call all the Notify() functions from each notification class.
Design client code
This is the last part of the example. We will create client code to set and make decisions about which notification will be fired.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ObserverPattern
{
class Program
{
static void Main(string[] args)
{
//Generate exception to notify all client
try
{
throw new ApplicationException("This is Exception");
}
catch (Exception ex)
{
INotifyObserver obj1 = new MailNotify();
INotifyObserver obj2 = new SMSNotify();
clsNotifier O = new clsNotifier();
O.AddService(obj1);
O.AddService(obj2);
O.ExecuteNotifier();
}
Console.ReadLine();
}
}
}
Here, we are generating ApplicationException() and within the Catch block we are creating an object to the MailNotification and SMSnotification class.
The executeNotifier() will call all Notify() functions from each notification class.
Output