Definition:
"Factory Pattern facilitates to create an instance of several derived classes."
Factory pattern provides the responsibility of object instantiation to a specific class(Factory class).
Description:
The client application needs to have an instance of specific class(or product) based on input type. Factory pattern allows to create an instance of a specific class(or product) based on client input type. However, the object instantiation process is not exposed to client application and object instantiation process is handled by Factory class. The client application refers to the newly instantiated object through abstract interface(product interface).
What are you achieving with the help of Factory pattern?
What is the impact if you don’t use Factory pattern ?
Program without Factory Pattern:
Abstract Product(MealPlan) : abstract product class defines the signature for generating meal plan.
Concreate Products(WeeklyPlan & MonthlyPlan) : implements abstract product class and generates the meal plan.
Client(NoFactoryClient) : client application class, initialize WeeklyPlan and MonthlyPlan objects and generates the meal plan by invoking GenerateMealPlan method.
public enum CuisineType { American = 1, Asian = 2, European = 3, Oceanian = 4 } public enum MealType { Breakfast = 1, Lunch = 2, Dinner = 3 } public enum MealPlanType { Weekly = 1, Monthly = 2, Custom = 3 } public class Meal { public int MealId { get; set; } public string MealName { get; set; } public MealType MealType { get; set; } public CuisineType CuisineType { get; set; } } public abstract class MealPlan { public abstract ListGenerateMealPlan(DateTime startDate, DateTime endDate); } public class WeeklyPlan : MealPlan { public override List GenerateMealPlan(DateTime startDate, DateTime endDate) { Console.WriteLine("Generated weekly meal plan"); return new List (); } } public class MonthlyPlan : MealPlan { public override List GenerateMealPlan(DateTime startDate, DateTime endDate) { Console.WriteLine("Generated monthly meal plan"); return new List (); } } class NoFactoryClient { static void Main(string[] args) { MealPlan weeklyPlan = new WeeklyPlan(); weeklyPlan.GenerateMealPlan(Convert.ToDateTime("Jan-01-2017"), Convert.ToDateTime("Jan-07-2017")); MealPlan monthlyPlan = new MonthlyPlan(); monthlyPlan.GenerateMealPlan(Convert.ToDateTime("Jan-01-2017"), Convert.ToDateTime("Jan-31-2017")); Console.ReadKey(); } }
Issue in a program without Factory:
How to fix this issue in a program using Factory Pattern:
Abstract Product(MealPlan) : no change as compared to program without factory.
Concreate Products( WeeklyPlan & MonthlyPlan) : no change as compared to program without factory.
Factory(MealPlanFactory) : newly added class as compared to program without factory. This class handles the responsibility of object(product) instantiation process.
Client(FactoryPattern) : client application class, interacts with MealPlanFactory class for getting the instance of WeeklyPlan and MonthlyPlan objects and generates the meal plan by invoking GenerateMealPlan method.
public abstract class MealPlan { public abstract ListGenerateMealPlan(DateTime startDate, DateTime endDate); } public class WeeklyPlan : MealPlan { public override List GenerateMealPlan(DateTime startDate, DateTime endDate) { Console.WriteLine("Generated weekly meal plan"); return new List (); } } public class MonthlyPlan : MealPlan { public override List GenerateMealPlan(DateTime startDate, DateTime endDate) { Console.WriteLine("Generated monthly meal plan"); return new List (); } } public class MealPlanFactory { public MealPlan GetMealPlanInstance(MealPlanType planType) { switch(planType) { case MealPlanType.Weekly: return new WeeklyPlan(); case MealPlanType.Monthly: return new MonthlyPlan(); default: throw new NotSupportedException(); } } } class FactoryPattern { static void Main(string[] args) { MealPlanFactory planFactory = new MealPlanFactory(); MealPlan mealPlan = planFactory.GetMealPlanInstance(MealPlanType.Weekly); mealPlan.GenerateMealPlan(Convert.ToDateTime("Jan-01-2017"), Convert.ToDateTime("Jan-07-2017")); mealPlan = planFactory.GetMealPlanInstance(MealPlanType.Monthly); mealPlan.GenerateMealPlan(Convert.ToDateTime("Jan-01-2017"), Convert.ToDateTime("Jan-31-2017")); Console.ReadKey(); } }