Can someone please critique my Factory Pattern??

Posts   
 
    
adminJaxon
User
Posts: 5
Joined: 02-Aug-2010
# Posted on: 03-Aug-2010 16:11:46   

Hello, I have recently been learning more about design patterns and thought I'd take a crack at it. I'm not sure if this is the correct way to use the factory pattern and was wondering if someone could provide me with feedback?

Thanks!

adminJaxon
User
Posts: 5
Joined: 02-Aug-2010
# Posted on: 03-Aug-2010 16:16:57   

Here is the basics of what I'm doing for those of you that don't want to open the project from the file:

I basically have a set calendar items. Meals, workouts and measurements. They all have a date and a name and can print details. but other than that they have a few items they each need differently.


    public enum AppointmentType
    {
        Workout,
        Meal,
        Measurement
    }

    public abstract class Appointment
    {
        public string Name { get; set; }
        public DateTime DateStarted { get; set; }

        public virtual string PrintDetails()
        {
            return string.Format("Type: {0}\nName: {1}\nDate: {2}",this.GetType().ToString(), Name, DateStarted.ToShortDateString());
        }
    }

    public class Workout : Appointment
    {
        public List<string> Exercises { get; set; }

        public Workout()
        {
            Exercises = new List<string>();
        }

        public override string PrintDetails()
        {
            string startInfo = base.PrintDetails();
            string addedInfo = "\nToday I will be doing the following:\n";

            foreach (string exercise in Exercises)
            {
                addedInfo += string.Format("{0}\n", exercise);
            }

            return startInfo + addedInfo;
        }
    }

    public class Meal : Appointment
    {
        public List<string> FoodItems { get; set; }

        public Meal()
        {
            FoodItems = new List<string>();
        }

        public override string PrintDetails()
        {
            string startInfo = base.PrintDetails();
            string addedInfo = "\nToday I will be eating the following:\n";

            foreach (string foodItem in FoodItems)
            {
                addedInfo += string.Format("{0}\n", foodItem);
            }

            return startInfo + addedInfo;
        }
    }

    public class Measurement : Appointment
    {
        public string Height { get; set; }
        public string Weight { get; set; }

        public override string PrintDetails()
        {
            string startInfo = base.PrintDetails();
            string addedInfo = string.Format("\nI am {0} feet tall and I weight {1} pounds!\n", Height, Weight);
            return startInfo + addedInfo;
        }
    }

    public interface IAppointmentFactory
    {
        Appointment CreateAppointment(AppointmentType appointmentType);
    }

    public class AppointmentFactory : IAppointmentFactory
    {
        public Appointment CreateAppointment(AppointmentType appointmentType)
        {
            switch (appointmentType)
            {
                case AppointmentType.Workout:
                    return new Workout();
                case AppointmentType.Meal:
                    return new Meal();
                case AppointmentType.Measurement:
                    return new Measurement();
                default:
                    return new Workout();
            }
        }
    }

adminJaxon
User
Posts: 5
Joined: 02-Aug-2010
# Posted on: 03-Aug-2010 16:18:30   

Here is a program that uses the appointment factory: Am I doing this correctly? Or am I missing the point of a factory? THANKS!


    class Program
    {
        public static List<Appointment> myAppointments;
        public static AppointmentFactory factory;
        public static Appointment myAppointment;

        static void Main(string[] args)
        {
            myAppointments = new List<Appointment>();
            factory = new AppointmentFactory();
            StartLoop();
        }

        private static void StartLoop()
        {
            Console.WriteLine(string.Format("\nWelcome to Appointment App: You have {0} appointment(s)!", myAppointments.Count()));
            Console.WriteLine("0 = Exit");
            Console.WriteLine("1 = New Workout");
            Console.WriteLine("2 = New Meal");
            Console.WriteLine("3 = New Measurement");
            Console.WriteLine("P = Print Schedule\n");

            switch (Console.ReadLine().ToUpper())
            {
                case "0":
                    return;
                case "1":
                    CreateNewAppointment(AppointmentType.Workout);
                    AddExercises();
                    break;
                case "2":
                    CreateNewAppointment(AppointmentType.Meal);
                    AddFoodItems();
                    break;
                case "3":
                    CreateNewAppointment(AppointmentType.Measurement);
                    GetMeasurements();
                    break;
                case "P":
                    PrintSchedule();
                    break;
                default:
                    return;
            }

            StartLoop();
        }

        private static void GetMeasurements()
        {
            Console.WriteLine("How tall are you?");
            ((Measurement)myAppointment).Height = Console.ReadLine();
            Console.WriteLine("What is your weight?");
            ((Measurement)myAppointment).Weight = Console.ReadLine();
        }

        private static void AddFoodItems()
        {
            Console.WriteLine("How many food items do you want to add?");
            string exerciseCount = Console.ReadLine();

            for (int i = 0; i < Convert.ToInt32(exerciseCount); i++)
            {
                Console.WriteLine(string.Format("Food {0}:", (i + 1)));
                ((Meal)myAppointment).FoodItems.Add(Console.ReadLine());
            }
        }

        private static void AddExercises()
        {
            Console.WriteLine("How many exercises do you want to add?");
            string exerciseCount = Console.ReadLine();
            
            for (int i = 0; i < Convert.ToInt32(exerciseCount); i++)
            {
                Console.WriteLine(string.Format("Exercise {0}:", (i + 1)));
                ((Workout)myAppointment).Exercises.Add(Console.ReadLine());
            }
        }

        private static void PrintSchedule()
        {
            foreach (Appointment appointment in myAppointments)
            {
                Console.WriteLine(appointment.PrintDetails());
            }
        }

        public static void CreateNewAppointment(AppointmentType appointmentType)
        {
            myAppointment = factory.CreateAppointment(appointmentType);

            Console.WriteLine("Name:");
            myAppointment.Name = Console.ReadLine();
            Console.WriteLine("Start Date:");
            myAppointment.Name = Console.ReadLine();

            myAppointments.Add(myAppointment);
        }
    }

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 03-Aug-2010 16:28:59   

There is a good discussion about Factory patterns at http://stackoverflow.com/questions/806911/is-this-factory-method-creation-pattern

Yours certainly looks along the right lines simple_smile

Matt

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 03-Aug-2010 18:58:44   

I removed the .zip because it contained a lot of binary files.

Frans Bouma | Lead developer LLBLGen Pro
adminJaxon
User
Posts: 5
Joined: 02-Aug-2010
# Posted on: 03-Aug-2010 20:10:59   

Otis wrote:

I removed the .zip because it contained a lot of binary files.

My bad Frans! I'm sorry, I thought I had removed them all. I must have ran the app again before I zipped it.

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 03-Aug-2010 21:18:24   

No problem - To be honest StackOverflow is a much better bet for these sort of general architecture questions - it has much bigger and more general audience. Due to the way the support shifts are organised we don't always have much spare time to get involved in long architectural discussions - much as we all like to... simple_smile

Matt

adminJaxon
User
Posts: 5
Joined: 02-Aug-2010
# Posted on: 03-Aug-2010 21:19:59   

MTrinder wrote:

No problem - To be honest StackOverflow is a much better bet for these sort of general architecture questions - it has much bigger and more general audience. Due to the way the support shifts are organised we don't always have much spare time to get involved in long architectural discussions - much as we all like to... simple_smile

Matt

Thanks! I will try SO and give that a go simple_smile

MTrinder
User
Posts: 1461
Joined: 08-Oct-2008
# Posted on: 03-Aug-2010 21:27:30   

No problem, always happy to help - even if occasionally it does mean pointing you in a different direction!

Matt