Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Strategy Design Pattern (Case Study)

4.83/5 (18 votes)
19 Aug 2009CPOL2 min read 63.2K   282  
This article shows a case study about how we use the strategy pattern to a daycare center.

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:

  1. Give the Kids exam
  2. Give the parent's Billing information
  3. 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

Strategy.JPG

Class Diagram

StrategyClassDiagram.JPG

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.

C#
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.

C#
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()
            {
                //exam starts
                Console.WriteLine("Dr. WANG (Eye doctor) starts examination for 
						" + aKid.Name + " ....");
                //step 1
                Console.WriteLine("Distance Vision Eye Test in process...");
                //step 2
                Console.WriteLine("Near Vision Test in process...");
                //step 3
                Console.WriteLine("Amsler Grid Eye Test in process...");
                //step 4
                Console.WriteLine("Exam completed for" + aKid.Name);

            }

            public override void GenerateBill()
            {
                Console.WriteLine("Generating the billing info...");
                Console.WriteLine("Examination Fee : $" + examFee);
                //apply the discount for kids
                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...");

                //I hardcode the condition here for demo only.
                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.

C#
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()
            {
                //exam starts
                Console.WriteLine("Dr. Fong (SLP) 
			starts examination for " + aKid.Name + " ....");
                //step 1
                Console.WriteLine("Listening Test in process...");
                //step 2
                Console.WriteLine("Spelling Test in process...");
                //step 3
                Console.WriteLine("Speech Test in process...");
                //step 4
                Console.WriteLine("Exam completed for" + aKid.Name);
            }

            public override void GenerateBill()
            {
                Console.WriteLine("Generating the billing info...");
                Console.WriteLine("Examination Fee : $" + examFee);
                //apply the discount for kids
                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.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace www.askbargains.com.Strategy
{
    //Context class
    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.

C#
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.

C#
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)
            {
                //initialize a daycare object  
                DaycareContext aDayCare = new DaycareContext();

                //Kid Elizabeth is created
                Kid kid1 = new Kid();
                kid1.Name = "Elizabeth";
                kid1.Age = 3;

                //Kid Aimee is created
                Kid kid2 = new Kid();
                kid2.Name = "Aimee";
                kid2.Age = 4;

                //add two kids to the aDayCare object
                aDayCare.Kids.Add(kid1);
                aDayCare.Kids.Add(kid2);

                //Client determines the condition for which doctor needs to be involved.
                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;
                }

                //loop all the kids 
                foreach (Kid oneKid in aDayCare.Kids)
                {
                    //assign the particular kid to the doctor for the exam
                    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!

result.JPG

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)