Today I want to discuss with you how to implement Observer design pattern using delegate and event in asp.net /c#.
Observer Pattern
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar Model View Controller (MVC) architectural pattern.(wikipedia).
UML class diagram of Observer pattern(wikipedia)
Code:
IObservable.cs
namespace ObserverDesignPatternLib
{
public delegate void NotifyObserver(string key);
internal interface IObservable
{
void AddObserver(NotifyObserver ob);
void RemoveObserver(NotifyObserver ob);
void Notify(string observerName);
}
}
----------------------------------------------
ObservableObject.cs
namespace ObserverDesignPatternLib
{
public class ObservableObject:IObservable
{
public event NotifyObserver NotifyObserverEvent;
public void AddObserver(NotifyObserver ob)
{
NotifyObserverEvent += ob;
}
public void RemoveObserver(NotifyObserver ob)
{
NotifyObserverEvent -= ob;
}
public void Notify(string observerName)
{
if (NotifyObserverEvent != null)
{
NotifyObserverEvent(observerName);
}
}
}
}
-----------------------------------------------
Status.cs
public class Status
{
public string Description { get; set; }
public DateTime UpdatedOn { get; set; }
public Status(string notes)
{
Description = notes;
UpdatedOn = DateTime.Now;
}
}
----------------------------------------
Patient .cs
public class Patient : ObservableObject
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
private Status _patientStatus;
public Status PatientStatus
{
get { return _patientStatus; }
set
{
_patientStatus = value;
Notify(this.Name);
}
}
}
----------------------------------------
Doctor.cs
public class Doctor
{
private Dictionary _patients = new Dictionary();
public Dictionary Patients
{
get { return _patients; }
set { _patients = value; }
}
public void RecivePatientStatus(string paitientName)
{
Console.WriteLine("Doctor received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
Patients[paitientName].Name,
Patients[paitientName].Age,
Patients[paitientName].Address,
Patients[paitientName].PatientStatus.UpdatedOn,
Patients[paitientName].PatientStatus.Description);
}
}
---------------------------------------------
Relative.cs
public class Relative
{
private Dictionary _patients = new Dictionary();
public Dictionary Patients
{
get { return _patients; }
set { _patients = value; }
}
public void PatientStatusUpdate(string key)
{
Console.WriteLine("Relative received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
Patients[key].Name,
Patients[key].Age,
Patients[key].Address,
Patients[key].PatientStatus.UpdatedOn,
Patients[key].PatientStatus.Description);
}
}
------------------------------------------------
Progarm.cs
class Program
{
static void Main(string[] args)
{
//Two Patients been created
var patientFever = new Patient();
var patientDiarhoea = new Patient();
patientFever.Name = "Al Amin";
patientFever.Age = 15;
patientFever.Address = "Gulshan,Dhaka";
patientDiarhoea.Name = "Abdul Gaffar";
patientDiarhoea.Age = 22;
patientDiarhoea.Address = "Mehedibag,Chittagong.";
//Relative object created for each patient
var relativeFever = new Relative();
relativeFever.Patients.Add(patientFever.Name, patientFever);
var relativeDiarhoea = new Relative();
relativeDiarhoea.Patients.Add(patientDiarhoea.Name, patientDiarhoea);
//one doctor object created
//this doctor is hospital's duty doctor, he is notified patient status time to time
var doctor = new Doctor();
doctor.Patients.Add(patientFever.Name, patientFever);
doctor.Patients.Add(patientDiarhoea.Name, patientDiarhoea);
//hospital also send status to the relatives.
patientFever.AddObserver(new NotifyObserver(relativeFever.PatientStatusUpdate));
patientDiarhoea.AddObserver(new NotifyObserver(relativeDiarhoea.PatientStatusUpdate));
//Update status for both Patients. relatives will receive the status at the same time
patientFever.PatientStatus = new Status(String.Format("{0} is feeling bed.", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is ", patientDiarhoea.Name));
//Updates the status after 2 secs
Thread.Sleep(2000);
//after 5 secs, patientDiarhoea doesn't feel well. need to get doctor involved
patientFever.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));
patientDiarhoea.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));
//update two Patients' status.
//relatives will recive their Patients status
//Doctor start reciving patient's status
patientFever.PatientStatus = new Status(String.Format("{0} is feel out of sort. Temparature : 102 F", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is sick due to in digest.", patientDiarhoea.Name));
//Updates the status after 3 secs
Thread.Sleep(3000);
//update two Patients' status
patientFever.PatientStatus = new Status(String.Format("{0} is not feel better. Still Temparature : 100 F", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is back to normal but weak.", patientDiarhoea.Name));
//Updates the status after 3 secs
Thread.Sleep(3000);
//since patient is become better. hospital's unsubscribe the doctor's observation
patientDiarhoea.RemoveObserver(new NotifyObserver(doctor.RecivePatientStatus));
//update two Patients' status
patientFever.PatientStatus = new Status(String.Format("{0} is now back to normal.", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is recover weakness.", patientDiarhoea.Name));
Console.WriteLine("Patients regular status report.");
Console.Read();
}
}
Final output
Observer Pattern
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems. The Observer pattern is also a key part in the familiar Model View Controller (MVC) architectural pattern.(wikipedia).
UML class diagram of Observer pattern(wikipedia)
The Observer Pattern describes the dependence relationship between one object (observable) to many objects (observers). It's also called Model/View, Dependents, or Distributor/Listener pattern.This article introduces an implementation when we can use the Observer pattern to keep all observer objects updated after things have changed.
Case project
In this case, patient is an ObservableObject that needs to send out the notification when the hospital updates his/her physical status. The hospital will determine who will be notified when the patient status is updated.
In our scenario, patient (observable object) admitted in hospital and they are observed by multiple observer (relative and doctor). Each observer get multiple time physical updated status from hospital daily.
Sample Class diagram for our case project
IObservable.cs
namespace ObserverDesignPatternLib
{
public delegate void NotifyObserver(string key);
internal interface IObservable
{
void AddObserver(NotifyObserver ob);
void RemoveObserver(NotifyObserver ob);
void Notify(string observerName);
}
}
----------------------------------------------
ObservableObject.cs
namespace ObserverDesignPatternLib
{
public class ObservableObject:IObservable
{
public event NotifyObserver NotifyObserverEvent;
public void AddObserver(NotifyObserver ob)
{
NotifyObserverEvent += ob;
}
public void RemoveObserver(NotifyObserver ob)
{
NotifyObserverEvent -= ob;
}
public void Notify(string observerName)
{
if (NotifyObserverEvent != null)
{
NotifyObserverEvent(observerName);
}
}
}
}
-----------------------------------------------
Status.cs
public class Status
{
public string Description { get; set; }
public DateTime UpdatedOn { get; set; }
public Status(string notes)
{
Description = notes;
UpdatedOn = DateTime.Now;
}
}
----------------------------------------
Patient .cs
public class Patient : ObservableObject
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
private Status _patientStatus;
public Status PatientStatus
{
get { return _patientStatus; }
set
{
_patientStatus = value;
Notify(this.Name);
}
}
}
----------------------------------------
Doctor.cs
public class Doctor
{
private Dictionary
public Dictionary
{
get { return _patients; }
set { _patients = value; }
}
public void RecivePatientStatus(string paitientName)
{
Console.WriteLine("Doctor received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
Patients[paitientName].Name,
Patients[paitientName].Age,
Patients[paitientName].Address,
Patients[paitientName].PatientStatus.UpdatedOn,
Patients[paitientName].PatientStatus.Description);
}
}
---------------------------------------------
Relative.cs
public class Relative
{
private Dictionary
public Dictionary
{
get { return _patients; }
set { _patients = value; }
}
public void PatientStatusUpdate(string key)
{
Console.WriteLine("Relative received {0}'s new status:\nAge: {1}\nAddress:{2}\nUpdates on: {3}\nDescription: {4} \n\n",
Patients[key].Name,
Patients[key].Age,
Patients[key].Address,
Patients[key].PatientStatus.UpdatedOn,
Patients[key].PatientStatus.Description);
}
}
------------------------------------------------
Progarm.cs
class Program
{
static void Main(string[] args)
{
//Two Patients been created
var patientFever = new Patient();
var patientDiarhoea = new Patient();
patientFever.Name = "Al Amin";
patientFever.Age = 15;
patientFever.Address = "Gulshan,Dhaka";
patientDiarhoea.Name = "Abdul Gaffar";
patientDiarhoea.Age = 22;
patientDiarhoea.Address = "Mehedibag,Chittagong.";
//Relative object created for each patient
var relativeFever = new Relative();
relativeFever.Patients.Add(patientFever.Name, patientFever);
var relativeDiarhoea = new Relative();
relativeDiarhoea.Patients.Add(patientDiarhoea.Name, patientDiarhoea);
//one doctor object created
//this doctor is hospital's duty doctor, he is notified patient status time to time
var doctor = new Doctor();
doctor.Patients.Add(patientFever.Name, patientFever);
doctor.Patients.Add(patientDiarhoea.Name, patientDiarhoea);
//hospital also send status to the relatives.
patientFever.AddObserver(new NotifyObserver(relativeFever.PatientStatusUpdate));
patientDiarhoea.AddObserver(new NotifyObserver(relativeDiarhoea.PatientStatusUpdate));
//Update status for both Patients. relatives will receive the status at the same time
patientFever.PatientStatus = new Status(String.Format("{0} is feeling bed.", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is ", patientDiarhoea.Name));
//Updates the status after 2 secs
Thread.Sleep(2000);
//after 5 secs, patientDiarhoea doesn't feel well. need to get doctor involved
patientFever.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));
patientDiarhoea.AddObserver(new NotifyObserver(doctor.RecivePatientStatus));
//update two Patients' status.
//relatives will recive their Patients status
//Doctor start reciving patient's status
patientFever.PatientStatus = new Status(String.Format("{0} is feel out of sort. Temparature : 102 F", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is sick due to in digest.", patientDiarhoea.Name));
//Updates the status after 3 secs
Thread.Sleep(3000);
//update two Patients' status
patientFever.PatientStatus = new Status(String.Format("{0} is not feel better. Still Temparature : 100 F", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is back to normal but weak.", patientDiarhoea.Name));
//Updates the status after 3 secs
Thread.Sleep(3000);
//since patient is become better. hospital's unsubscribe the doctor's observation
patientDiarhoea.RemoveObserver(new NotifyObserver(doctor.RecivePatientStatus));
//update two Patients' status
patientFever.PatientStatus = new Status(String.Format("{0} is now back to normal.", patientFever.Name));
patientDiarhoea.PatientStatus = new Status(String.Format("{0} is recover weakness.", patientDiarhoea.Name));
Console.WriteLine("Patients regular status report.");
Console.Read();
}
}
Final output
5 comments:
Very easy to understand ..thanks..carry on
Superb article...I like it...
Clear and easy explanation.Thanks
You have given very nice post it is very knowledgable and result oriented.
Website is very good tool for any company.
This is very useful information shared here. I am really thankful for this. 99th.co.in64884 105
Post a Comment