Background
Again, my favor place - Elizabeth's daycare center.
In my family, my wife and I both need to work everyday, therefore we drop our kids to the daycare center from 8:00 am to 5:00 pm. I have used my daughter's daycare center in my other articles as well.
On Elizabeth's daycare calendar, it shows the Dr. WANG (EyeDoctor) give the eye screen on 15th each month for all the kids, Dr. Fong (SLP - Speech Language Pathologist) gives the speech exam on 28th each month.
For each doctor's visit, three major activities need to be done:
- Give the Kids exam
- Give the parent's Billing information
- Send the evaluation result to the kid's parents
Remember, what needs to be completed in each step will be different, and it will also be controlled by the strategy object (Doctor). What situation to apply to which strategy object(Doctor) was decided by the client side (Daycare).
Introduction
The Strategy Pattern describes how we package the individual work process from multiple objects when those objects need to have their own strategy for the same action. It can isolate the details to be involved from the environment. Context object could take the benefits from the action changes dynamically when the strategy object changed. It's also called Policy pattern. This article introduces an implementation how we use the strategy pattern to our daycare center.
Strategy Design Pattern Structure
Class Diagram
Implementation Code
Strategy Objects
Doctor
Doctor
class is our base abstract
strategy class. It defines the basic activities here to allow the child class to implement the details.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace Strategy
{
abstract public class Doctor
{
public Kid aKid { get; set; }
abstract public void ExamineKid();
abstract public void GenerateBill();
abstract public void CreateReport();
}
}
}
EyeDoctor
In my EyeDoctor
class, I implemented all the details in those activities which it inherits from the base Doctor
class. For example: In the GenerateBill
method, EyeDoctor
gives a different discount rate based on the children's age.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace Strategy
{
public class EyeDoctor : Doctor
{
const int examFee = 80;
public override void ExamineKid()
{
Console.WriteLine("Dr. WANG (Eye doctor) starts examination for
" + aKid.Name + " ....");
Console.WriteLine("Distance Vision Eye Test in process...");
Console.WriteLine("Near Vision Test in process...");
Console.WriteLine("Amsler Grid Eye Test in process...");
Console.WriteLine("Exam completed for" + aKid.Name);
}
public override void GenerateBill()
{
Console.WriteLine("Generating the billing info...");
Console.WriteLine("Examination Fee : $" + examFee);
switch (aKid.Age)
{
case 3:
Console.WriteLine("Extra 25% discount is applied for
" + aKid.Name);
Console.WriteLine("Total due: " + examFee * (1 - 0.25));
break;
case 4:
Console.WriteLine("Extra 25% discount for " + aKid.Name);
Console.WriteLine("Total due: " + examFee * (1 - 0.15));
break;
default:
Console.WriteLine("Extra 10% discount for " + aKid.Name);
Console.WriteLine("Total due: " + examFee * (1 - 0.10));
break;
}
}
public override void CreateReport()
{
Console.WriteLine("Writing the report...");
if (aKid.Name == "Elizabeth")
Console.WriteLine(aKid.Name + " needs the follow up check.
please contact us...");
else
Console.WriteLine(aKid.Name + " is fine. Thanks. ");
}
}
}
}
SLP
Same as EyeDoctor
, SLP has its own rules to implement the base activities.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace Strategy
{
public class SLP : Doctor
{
const int examFee = 180;
public override void ExamineKid()
{
Console.WriteLine("Dr. Fong (SLP)
starts examination for " + aKid.Name + " ....");
Console.WriteLine("Listening Test in process...");
Console.WriteLine("Spelling Test in process...");
Console.WriteLine("Speech Test in process...");
Console.WriteLine("Exam completed for" + aKid.Name);
}
public override void GenerateBill()
{
Console.WriteLine("Generating the billing info...");
Console.WriteLine("Examination Fee : $" + examFee);
switch (aKid.Age)
{
case 3:
Console.WriteLine("Extra 5%
discount is applied for " + aKid.Name);
Console.WriteLine("Total due: " + examFee * (1 - 0.05));
break;
default:
Console.WriteLine("Extra 10% discount for " + aKid.Name);
Console.WriteLine("Total due: " + examFee * (1 - 0.10));
break;
}
}
public override void CreateReport()
{
Console.WriteLine("Writing the report...");
Console.WriteLine("We recommend " + aKid.Name +
" to join our practice session on every Wednesday. Thanks.");
}
}
}
}
Context Object
DaycareContext
DaycareContext
class acts as protocol class to handle the communication from our client to the strategy object. It declares a strategy object (Doctor_on_Duty
) in the local. It also contains a collection object (List<kid> Kids) to maintain all kids information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com.Strategy
{
public class DaycareContext
{
public List<kid /> Kids = new List<kid />();
public Doctor Doctor_on_Duty { get; set; }
public void StartDoctorActivies()
{
Doctor_on_Duty.ExamineKid();
Doctor_on_Duty.GenerateBill();
Doctor_on_Duty.CreateReport();
}
}
}
Kid Class
Kid
class in here is a helper class that holds the personal information for each child.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace www.askbargains.com
{
namespace Strategy
{
public class Kid
{
public string Name { get; set; }
public int Age { get; set; }
}
}
}
Client App
From the client side, I create two kids and add them to the daycare. A console application will request client to give the date to simulate the real case. If user provides 15 as the date, then it must have EyeDoctor
visit, and 28 is SLP doctor visit.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using www.askbargains.com.Strategy;
namespace www.askbargains.com
{
namespace Client
{
class Program
{
static void Main(string[] args)
{
DaycareContext aDayCare = new DaycareContext();
Kid kid1 = new Kid();
kid1.Name = "Elizabeth";
kid1.Age = 3;
Kid kid2 = new Kid();
kid2.Name = "Aimee";
kid2.Age = 4;
aDayCare.Kids.Add(kid1);
aDayCare.Kids.Add(kid2);
Console.WriteLine("Please type today's Date ==> (DD)");
string date = Console.ReadLine();
switch (date)
{
case "15":
aDayCare.Doctor_on_Duty = new EyeDoctor();
break;
case "28":
aDayCare.Doctor_on_Duty = new SLP();
break;
default:
Console.WriteLine("No doctor visit today");
break;
}
foreach (Kid oneKid in aDayCare.Kids)
{
aDayCare.Doctor_on_Duty.aKid = oneKid;
Console.WriteLine();
aDayCare.StartDoctorActivies();
}
Console.ReadLine();
}
}
}
}
Once we start our client app, you will see all the messages related to each Dr. activities. Cool!
Conclusion
From this article, I demonstrated how we can use Strategy Pattern to achieve the implementation for a Daycare Doctor visits. I also use the daycare center for the Observer Design pattern in my other article.