Inspiration
While going through these 2 patterns (Factory Method Pattern and Abstract Factory Pattern), I always wondered they have a similarity in name; should there be some similarity in their code as well. However, I never got any single case study which could be used for both the patterns. Actually, they both work at different levels and can’t be compared. I always wanted to use a single case study for illustrating both the patterns in the interest of understanding where they can or can’t be used.
Introduction
These are the patterns that fall under "Creation design patterns" category defined by “Gang of Four.”
- Abstract Factory pattern
Provides an interface for creating families of related or dependent objects without specifying their concrete classes. - Factory Method Pattern
Defines an interface for creating an object, but lets the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Who should read this article
- If you are a novice at abstract factory & factory method pattern.
- If you are confused between the abstract factory pattern and factory method pattern.
- If you have gone through many examples related to the abstract factory and factory method, but still unable to bridge the gap between these two.
- If you want to know what each class in the pattern does and how.
- If you want to spot the exact place where changes happen while switching from factory to abstract factory.
About the Article
The actual programming scenario case may not be the same for both the patterns, but for making these complicated design patterns, I am taking a simple real-life example of a pack of the meal offered by a food store Tesco Express. I am using the same case study example so that the difference can be identified between these two design patterns.
This article will also highlight the differences between Abstract Factory and Factory method pattern.
A Real-world example – Meal Deal offered by Tesco Express
Factory Method Pattern
A real-world scenario,
In Programming Terms
- You – Main method
- Tesco Express – The Creator or Interface
- Customer service – The Concrete creator
- A definition of Meal deal – Abstract Product
- A pack of Meal deal – Concrete Product
Real-life conversation along with the implementation of the code with the factory method
A customer goes to Tesco Express and converses with customer service
- Customer– Hi, do you have any offer for the meal?
- Customer Service – Yes, why don’t you try our meal deal option? Here you can have 1 main meal, 1 snack, and 1 drink.
- Customer –Sure, what are the option available with it?
(Action - Customer Service checks for the options available.)
UI Code
- MealDeal_AbstractFactory oAbstractFactory_HighProtein = new Mealdeal_ConcreteFactory();
- oAbstractFactory_HighProtein.GetMainMealsOption_AbstractProduct();
- Console.ReadKey();
Customer Service – Sir, here are the options available under meal deal.
Output
Customer – Thank you very much!
Class Diagram

Whole code implementation for Abstract factory pattern.
UIClass.cs
- using System;
- namespace FactoryMethod_TescoMealDeal
- {
- class UIClass
- {
- static void Main(string[] args)
- {
- // Instantiating & Initializing the ConcreteFactory class to get the instance of its parent class AbstractFactory return
- MealDeal_CreatorFactory oAbstractFactory_HighProtein = new Mealdeal_ConcreteCreatorFactory();
- oAbstractFactory_HighProtein.GetMainMealsOption_AbstractProduct();
- Console.ReadKey();
- }
- }
- }
Creator.cs
- namespace FactoryMethod_TescoMealDeal
- {
- #region AbstractFactory
- /// <summary>
- /// Its abstract class defines factory method
- /// </summary>
- abstract class MealDeal_CreatorFactory
- {
- public abstract Mealdeal_AbstractProduct GetMainMealsOption_AbstractProduct();
- }
- #endregion
- #region ConcreteFactory
- /// <summary>
- /// The 'Mealdeal_ConcreteCreatorFactory' class :
- /// Object creation preocess of Concrete products takes place here
- /// Factory method - implement abstract method to return concrete product
- /// </summary>
- class Mealdeal_ConcreteCreatorFactory : MealDeal_CreatorFactory
- {
- public override Mealdeal_AbstractProduct GetMainMealsOption_AbstractProduct()
- {
- Mealdeal_AbstractProduct meal = new Mealdeal_ConcreteProduct();
- meal.GetMealdealOption();
- return meal;
- }
- }
- #endregion
- }
Product.cs
- using System;
- namespace FactoryMethod_TescoMealDeal
- {
- /// <summary>
- /// Abstract Class/Interface : it defines the method that how the actual product will be created
- /// </summary>
- abstract class Mealdeal_AbstractProduct
- {
- public abstract void GetMealdealOption();
- }
- class Mealdeal_ConcreteProduct : Mealdeal_AbstractProduct
- {
- public override void GetMealdealOption()
- {
- Console.WriteLine("Please select any one item from each of :\n sandwiches/salads/veg wraps as main meal \n and crisp/branchcolate/fruit as snacks \n and shakes/Smoothei/Water as drink");
- }
- }
- }
Observations
- UI Class instantiates the creator to produce a product.
- It produces 1 product
Points to note
- Where is it used – When the responsibility of an object creation to be delegated to a factory i.e., I want a meal deal (having the main meal, snack, & drink)
- How objects are created - The object of the product is being created using inheritance of creator method which defines the abstract product, as it says instantiation to be deferred to the subclass which is creator class here.
- Where objects are created - Inside concrete creator.
- What it produces - A single product.
- The caller of the factory – Here caller of the factory is the main class, who knows which concrete factory will be used to create a product.
- Creator/Factory – It just defines a method to produce a product but it does not know which child product is being produced.
Abstract Factory
Real world scenario
In Programming Terms
Comparing design pattern terms with a real-world example.
- Customer – Main method
- Tesco Express/Customer service - Client
- Meal pack (combination of one MainMeal + snacks + drink) - abstract factory
- Meal pack of high protein, low-calorie, high fiber meal – factory
- MainMeals, Snacks, Drink – Abstract product
- (High-protein Main, High-fibre snacks, Low-calorie Drinks etc.) – Concrete Product
Real life conversation along with abstract factory code will go like this.
Customer goes to Tesco Express and converses with the customer service,
- Customer– Hi, do you have any offer for a meal?
- Customer Service – Yes, why don’t you try our meal deal option? Here, you can have 1 main meal, 1 snack, and 1 drink.
- Customer –Sure, what are the option available with it?
- Action - Customer Service checks for the options available
UI Code
- MealDeal_AbstractFactory oAbstractFactory_HighProtein =new HighProtein_ConcreteFactory();
- Customer Service – What types of food you would like to have in your meal? We have 3 types of diet, high protein, high fiber, low-calorie.
- Customer – Thanks! I would like to go have the high protein in my meal, what items I can choose for this?
Customer service checks for the deal options for high-protein diet.
UICode
- SelectMealClient oMealClientHighProtein = new SelectMealClient(oAbstractFactory_HighProtein);
- oMealClientHighProtein.GetMealReady();
Client code
- class SelectMealClient
- {
- MainMeals_AbstractProduct oMain_AbstractProduct;
- Snacks_AbstractProduct oSnack_AbstractProduct;
- Drinks_AbstractProduct oDrink_AbstractProduct;
- public SelectMealClient(MealDeal_AbstractFactory oAbstractFactory)
- {
- oMain_AbstractProduct = oAbstractFactory.GetMainMealsOption_AbstractProduct();
- oSnack_AbstractProduct = oAbstractFactory.GetSnacksOption_AbstractProduct();
- oDrink_AbstractProduct = oAbstractFactory.GetDrinksOption_AbstractProduct();
- }
- // Invoking method defined in AbstractProduct implemented in ConcreteProduct
- public void GetMealReady()
- {
- oMain_AbstractProduct.GetMainMealsOption();
- oSnack_AbstractProduct.GetSnacksOption();
- oDrink_AbstractProduct.GetDrinksOption();
- }
- }
Output
Customer Service – You can have among sandwiches, crisps, and shakes.
Customer – Nice, may I know what I need to select if I go with High-fibre and Low-calorie diet.
Code for High-fibre diet,
UICode
- MealDeal_AbstractFactory oAbstractFactory_HighFibre = new HighFibre_ConcreteFactory();
- SelectMealClient oMealClientLowcalorie =
- new SelectMealClient(oAbstractFactory_Lowcalorie);
- oMealClientHighFibre.GetMealReady();
Client code – Same as previous.
Output
Code for Low-calorie diet,
UICode
- MealDeal_AbstractFactory oAbstractFactory_Lowcalorie = new LowCalorie_ConcreteFactory();
- SelectMealClient oMealClientHighFibre =
- new SelectMealClient(oAbstractFactory_HighFibre);
- oMealClientLowcalorie.GetMealReady();
Client code – Same as previous.
Output
Points to note
Here, you can see that more options are added, no change in client code is required.
Class Diagram

Whole Implementation Code for factory method patterns is mentioned below.
UIClass.cs
- using System;
- namespace AbstractFactory_TescoMealDeal
- {
- class UIClass
- {
- static void Main(string[] args)
- {
- // Instantiating ConcreteFactory class
- MealDeal_AbstractFactory oAbstractFactory_HighProtein = new HighProtein_ConcreteFactory();
- MealDeal_AbstractFactory oAbstractFactory_HighFibre = new HighFibre_ConcreteFactory();
- MealDeal_AbstractFactory oAbstractFactory_Lowcalorie = new LowCalorie_ConcreteFactory();
- // Instantiating & Initializing the Client class using constructor injection
- // in order to delegate the responsibility of invoking the method(s) defined inside the AbstractFactory
- SelectMealClient oMealClientHighProtein = new SelectMealClient(oAbstractFactory_HighProtein);
- SelectMealClient oMealClientHighFibre = new SelectMealClient(oAbstractFactory_HighFibre);
- SelectMealClient oMealClientLowcalorie = new SelectMealClient(oAbstractFactory_Lowcalorie);
- // Invoke the method to get the actual product using object of Client
- oMealClientHighProtein.GetMealReady();
- oMealClientHighFibre.GetMealReady();
- oMealClientLowcalorie.GetMealReady();
- Console.ReadKey();
- }
- }
- #region Client
- /// <summary>
- /// This decides how the final product will be prepared.
- /// </summary>
- class SelectMealClient
- {
- MainMeals_AbstractProduct oMain_AbstractProduct;
- Snacks_AbstractProduct oSnack_AbstractProduct;
- Drinks_AbstractProduct oDrink_AbstractProduct;
- // Client Constructor
- // Note - Client's constructor will use instance of AbstractFactory,
- // but having hidden information of ConcreteFactory(Child Factory)
- // this instance (parameter) will invoke the method defined in AbstractFactory,
- // but implemented in ConcreteFactory returning ConcreteProduct
- // which (the result of invoked class) will be assigned to the instance of AbstractProduct(Parent), we already declared above under Client
- public SelectMealClient(MealDeal_AbstractFactory oAbstractFactory)
- {
- oMain_AbstractProduct = oAbstractFactory.GetMainMealsOption_AbstractProduct();
- oSnack_AbstractProduct = oAbstractFactory.GetSnacksOption_AbstractProduct();
- oDrink_AbstractProduct = oAbstractFactory.GetDrinksOption_AbstractProduct();
- }
- // Invoking method defined in AbstractProduct implemented in ConcreteProduct
- public void GetMealReady()
- {
- oMain_AbstractProduct.GetMainMealsOption();
- oSnack_AbstractProduct.GetSnacksOption();
- oDrink_AbstractProduct.GetDrinksOption();
- }
- }
- #endregion
- }
Factory.cs
- namespace AbstractFactory_TescoMealDeal
- {
- #region AbstractFactory
- /// <summary>
- /// Here factory defines the AbstractProduct to be produced (could be in composition; decided by Client)
- /// but it does not know, what concrete product actually going to be produced.
- /// </summary>
- abstract class MealDeal_AbstractFactory
- {
- public abstract MainMeals_AbstractProduct GetMainMealsOption_AbstractProduct();
- public abstract Snacks_AbstractProduct GetSnacksOption_AbstractProduct();
- public abstract Drinks_AbstractProduct GetDrinksOption_AbstractProduct();
- }
- #endregion
- #region ConcreteFactory
- /// <summary>
- /// Object creation process of Concrete products takes place here
- /// this knows where to get the concrete product from
- /// </summary>
- /// <summary>
- /// The 'LowCalorie_ConcreteFactory' class
- /// </summary>
- class HighProtein_ConcreteFactory : MealDeal_AbstractFactory
- {
- public override MainMeals_AbstractProduct GetMainMealsOption_AbstractProduct()
- {
- return new HighProteinMain_ConcreteProduct();
- }
- public override Snacks_AbstractProduct GetSnacksOption_AbstractProduct()
- {
- return new HighProteinSnacks_ConcreteProduct();
- }
- public override Drinks_AbstractProduct GetDrinksOption_AbstractProduct()
- {
- return new HighProteinDrinks_ConcreteProduct();
- }
- }
- /// <summary>
- /// The 'HighFibre_ConcreteFactory' class
- /// </summary>
- class HighFibre_ConcreteFactory : MealDeal_AbstractFactory
- {
- public override MainMeals_AbstractProduct GetMainMealsOption_AbstractProduct()
- {
- return new HighFibreMain_ConcreteProduct();
- }
- public override Snacks_AbstractProduct GetSnacksOption_AbstractProduct()
- {
- return new HighFibreSnacks_ConcreteProduct();
- }
- public override Drinks_AbstractProduct GetDrinksOption_AbstractProduct()
- {
- return new HighFibreDrinks_ConcreteProduct();
- }
- }
- /// <summary>
- /// The 'LowCalorie_ConcreteFactory' class
- /// </summary>
- class LowCalorie_ConcreteFactory : MealDeal_AbstractFactory
- {
- public override MainMeals_AbstractProduct GetMainMealsOption_AbstractProduct()
- {
- return new LowCalorieMain_ConcreteProduct();
- }
- public override Snacks_AbstractProduct GetSnacksOption_AbstractProduct()
- {
- return new LowCalorieSnacks_ConcreteProduct();
- }
- public override Drinks_AbstractProduct GetDrinksOption_AbstractProduct()
- {
- return new LowCalorieDrinks_ConcreteProduct();
- }
- }
- #endregion
- }
Product.cs
- using System;
- namespace AbstractFactory_TescoMealDeal
- {
- #region AbstractProduct
- /// <summary>
- /// Abstract Class/Interface : it defines the method that how the actual product will be created
- /// </summary>
- abstract class MainMeals_AbstractProduct
- {
- public abstract void GetMainMealsOption();
- }
- abstract class Snacks_AbstractProduct
- {
- public abstract void GetSnacksOption();
- }
- abstract class Drinks_AbstractProduct
- {
- public abstract void GetDrinksOption();
- }
- #endregion
- #region ConcreteProduct
- /// <summary>
- /// The 'Main meal product to be returned from High protein Factory' class
- /// This is the place where, the functionality of implementating end product is defined.
- /// </summary>
- #region High Protien
- class HighProteinMain_ConcreteProduct : MainMeals_AbstractProduct
- {
- public override void GetMainMealsOption()
- {
- Console.WriteLine("Please select among chicken sandwiches");
- }
- }
- class HighProteinSnacks_ConcreteProduct : Snacks_AbstractProduct
- {
- public override void GetSnacksOption()
- {
- Console.WriteLine("Please select among Crisps");
- }
- }
- class HighProteinDrinks_ConcreteProduct : Drinks_AbstractProduct
- {
- public override void GetDrinksOption()
- {
- Console.WriteLine("Please select among Shakes");
- }
- }
- #endregion
- #region High Fibre
- class HighFibreMain_ConcreteProduct : MainMeals_AbstractProduct
- {
- public override void GetMainMealsOption()
- {
- Console.WriteLine("Please select among Salads");
- }
- }
- class HighFibreSnacks_ConcreteProduct : Snacks_AbstractProduct
- {
- public override void GetSnacksOption()
- {
- Console.WriteLine("Please select among BranChocolate");
- }
- }
- class HighFibreDrinks_ConcreteProduct : Drinks_AbstractProduct
- {
- public override void GetDrinksOption()
- {
- Console.WriteLine("Please select among Smoothies");
- }
- }
- #endregion
- #region Low Calorie
- class LowCalorieMain_ConcreteProduct : MainMeals_AbstractProduct
- {
- public override void GetMainMealsOption()
- {
- Console.WriteLine("Please select among veg wraps");
- }
- }
- class LowCalorieSnacks_ConcreteProduct : Snacks_AbstractProduct
- {
- public override void GetSnacksOption()
- {
- Console.WriteLine("Please select among any fruits");
- }
- }
- class LowCalorieDrinks_ConcreteProduct : Drinks_AbstractProduct
- {
- public override void GetDrinksOption()
- {
- Console.WriteLine("Please select among Water, caobonated water, lime water");
- }
- }
- #endregion
- #endregion
- }
Observation on Abstract Factory
- Abstract Product
- 1 abstract product is limited to 1 type of object implemented by a concrete product.
- 1 abstract product is limited to 1 type of object implemented by a concrete product.
- Abstract factory
- Abstract factory is responsible to make complete product includes family or composition of abstract products.
- Abstract factory is responsible to make complete product includes family or composition of abstract products.
- Client
- No changes take place in client code
- The client just receives the instance of the abstract factory (holds the reference of child/concrete factory) from main method (i.e. Customer says high fiber diet)
- Concrete factory
- Concrete factory knows which concrete product to be returned.
Points to Note
- Where is it used - Abstract factory is used to produce a composed product (or family of related products) based on 2 or more filters (i.e. I want a meal deal (having main meal, snack & drink) with high protein) or you can say “applying another level of abstraction over a factory method”.
- How an object is created - Objects are created using composition.
- Where objects are created - Concrete factories implement factory method to create a product.
- What it produces - It produces a family of a related object.
- The caller of a factory – Caller of a factory, (which is called client here) does not know which concrete factory will be used to create a product.
- Factory – It holds a method to produce a composition of products or its family but it does not even know which concrete factory will be used to create a specific product.
References
- https://www.dofactory.com/net/factory-method-design-pattern
Join the conversation! Your thoughts help the community grow.