Factory Method Design Pattern in C#

Factory Method Design Pattern in C# with Real-time Example

In this article, I am going to discuss the Factory Method Design Pattern in C# with an example. Please read our previous article where we discussed the Factory Design Pattern in C# with one real-time example. The Factory Method Design Pattern belongs to the Creational Pattern category and is one of the most frequently used design patterns in real-time applications. As part of this article, we are going to discuss the following pointers.

  1. What is Factory Method Design Pattern?
  2. Understanding the Factory Method Design Pattern with Real-time Example
  3. Implementing the Factory Method Design Pattern in C#
  4. When to use the Factory Method Design Pattern?

Note: The most important point that you need to remember is the Factory Method Design pattern is not the exact same as the simple Factory Design Pattern that we discussed in our previous article. Most people think that both are the same and thus they use the terms Factory and Factory method interchangeably which is not right.

What is Factory Method Design Pattern?

According to Gang of Four Definition “Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation it uses to subclasses”.

Let us simplify the above definition. The Factory Method Design Pattern is used, when we need to create the object (i.e. instance of the Product class) without exposing the object creation logic to the client. To achieve this, in the factory method design pattern we will create an abstract class as the Factory class which will create and return the instance of the product, but it will let the subclasses decide which class to instantiate. If this is not clear at the moment then don’t worry, I will explain this with one real-time example.

Understanding the Factory Method Design Pattern with Real-time Example:

Let us understand the Factory Method Design Pattern with one real-time example. We are going to develop an application for showing the credit card information.

Please have a look at the following image. As you can see in the below diagram, we have three credit cards i.e. MoneyBack, Titanium, and Platinum. These credit cards are nothing but our Product classes. Again these three Credit Card classes are the subclasses of the CreditCard super interface. The CreditCard super interface defines the operations (i.e. GetCardType, GetCreditLimit, and GetAnnualCharge) which need to be implemented by the subclasses (i.e. MoneyBack, Titanium, and Platinum).

Understanding Factory Method Pattern

As per the definition of the Factory Method Design Pattern, we need to create an abstract class or interface for creating the object. Please have a look at the following diagram. This is going to be our Creator class that declares the factory method, which will return an object of type Product (i.e. CreditCard).

Understanding Factory Method Pattern in C#

As you can see, the above abstract class (i.e. CreditCardFactory) contains two methods, one abstract method i.e. MakeProduct() and one concrete method i.e. CreateProduct(). The CreateProduct() method internally calls the MakeProduct() method of the subclass which will create the product instance and return that instance.

Please have a look at the following diagram. As we have three credit cards (i.e. MoneyBack, Platinum, and Titanium), so here we created three subclasses (i.e. PlatinumFactory, TitaniumFactory, and MoneyBackFactory) of the Abstract CreditCradFactory class and implement the MakeProduct method. This method is going to return the actual product object i.e. (MoneyBack, Platinum, and Titanium).

Factory Method Design Pattern in C# with Real-time Example

Now let see how the client is going to consume the above CreditCardFactory to create an object. Please have a look at the following diagram.

Factory Method Design Pattern in C#

As shown in the above image, the client wants to create the Platinum object. In order to do so, the clients call the CreateProduct method on the PlatinumFactory instance which will return a concrete product.

Implementing the Factory Method Design Pattern in C#:

Step1: Creating Product Interface

Create a class file with the name CreditCard.cs and then copy and paste the following code. This is going to be our Product interface which will provide the signature of the common functionalities which should be implemented by the concrete product classes.

namespace FactoryMethodDesignPattern
{
    public interface CreditCard
    {
        string GetCardType();
        int GetCreditLimit();
        int GetAnnualCharge();
    }
}
Step2: Creating Concrete Products

This is a class implementing the Product interface. As we have three types of Credit cards in our example, so we are going to create three classes (MoneyBack, Titanium, and Platinum) by implementing the CreditCard interface as shown below.

namespace FactoryMethodDesignPattern
{
    public class Platinum : CreditCard
    {
        public string GetCardType()
        {
            return "Platinum Plus";
        }
        public int GetCreditLimit()
        {
            return 35000;
        }
        public int GetAnnualCharge()
        {
            return 2000;
        }
    }
    public class Titanium : CreditCard
    {
        public string GetCardType()
        {
            return "Titanium Edge";
        }
        public int GetCreditLimit()
        {
            return 25000;
        }
        public int GetAnnualCharge()
        {
            return 1500;
        }
    }
    public class MoneyBack : CreditCard
    {
        public string GetCardType()
        {
            return "MoneyBack";
        }

        public int GetCreditLimit()
        {
            return 15000;
        }

        public int GetAnnualCharge()
        {
            return 500;
        }
    }
}
Step3: Creating Abstract Creator

The Abstract Creator declares the factory method, which returns an object of type Product. As per the definition, we need to create an abstract class or interface for creating the object. So, let us create an abstract class that will be our factory class with a publicly exposed method. That method is nothing but the factory method which will return the instance of the product.

So create a class file with the name CreditCardFactory.cs and then copy and paste the following code in it.

namespace FactoryMethodDesignPattern
{
    public abstract class CreditCardFactory
    {
        protected abstract CreditCard MakeProduct();

        public CreditCard CreateProduct()
        {
            return this.MakeProduct();
        }
    }
}

We created the above abstract class with one abstract method i.e. MakeProduct() and one concrete method i.e. CreateProduct(). The CreateProduct() method internally calls the MakeProduct() method of the subclass which will create the product instance and return that instance.

Step4: Creating Concrete Creator

The Concrete Creator object overrides the factory method to return an instance of a Concrete Product. As we have three types of Credit Card, so we are going to create three classes (PlatinumFactory, MoneyBackFactory, and TitaniumFactory) which will implement the abstract CreditCardFactory class.

So, create a class file with the name ConcreteCreator.cs and then copy and paste the following code in it.

namespace FactoryMethodDesignPattern
{
    public class MoneyBackFactory : CreditCardFactory
    {
        protected override CreditCard MakeProduct()
        {
            CreditCard product = new MoneyBack();
            return product;
        }
    }

    public class PlatinumFactory : CreditCardFactory
    {
        protected override CreditCard MakeProduct()
        {
            CreditCard product = new Platinum();
            return product;
        }
    }

    public class TitaniumFactory : CreditCardFactory
    {
        protected override CreditCard MakeProduct()
        {
            CreditCard product = new Titanium();
            return product;
        }
    }
}

As you can see the above three classes implement the MakeProduct method of the CreditCardFactory class. That’s it. We are done with our implementation. Let’s compare the Gang of Four Definition with our example.

According to Gang of Four, we need to define an interface or abstract class for creating an object. In our example, it is an abstract class i.e. CreditCardFactory class. The second part of the definition saying that let the subclasses decide which class to instantiate. In our example, the subclasses are PlatinumFactory, MoneyBackFactory, and TitaniumFactory. So these subclasses will decide which class to instantiate, for example, MoneyBack, Titanium, and Platinum.

Step5: Consuming the factory Method in the Client Code:

If you want to create an instance of the Platinum CreditCard then call the CreateProduct method of the PlatinumFactory instance, similarly, if you want the instance of Titanium CreditCard, then call the CreateProduct method of the TitaniumFactory instance.

So modify the Main method as shown below.

using System;
namespace FactoryMethodDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            
            CreditCard creditCard = new PlatinumFactory().CreateProduct();
            if (creditCard != null)
            {
                Console.WriteLine("Card Type : " + creditCard.GetCardType());
                Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit());
                Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge());
            }
            else
            {
                Console.Write("Invalid Card Type");
            }
            Console.WriteLine("--------------");
            creditCard = new MoneyBackFactory().CreateProduct();
            if (creditCard != null)
            {
                Console.WriteLine("Card Type : " + creditCard.GetCardType());
                Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit());
                Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge());
            }
            else
            {
                Console.Write("Invalid Card Type");
            }
            Console.ReadLine();
        }
    }
}

When we run the application, it displays the output as expected as shown below.

Real-time example of Factory Method Pattern in C#

In the next article, I am going to discuss the Abstract Factory Design Pattern in C# with an example. In this article, I try to explain the Factory Method Design Pattern in C# step by step with an example. I hope this article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.

16 thoughts on “Factory Method Design Pattern in C#”

  1. On your another article “Factory Design Pattern in C#”, you mentioned one of disadvantages of Simple Factory Design Pattern is the need to add new if-else should we need to add new product, which violates open-closed principle:
    https://dotnettutorials.net/lesson/factory-design-pattern-csharp/

    In the end of article above, you mentioned that Factory Method design pattern could overcome the above problem, but I still see if-else used in CreditCardFactory class of this example.

    Would you please advise?

    Thank you!

    1. I agree with DK, I dont see the point, How is adding all this complication better than just doing CreditCard creditcard = new MoneyBack(); ???

  2. The if else used on the client is nothing more than defensive programming.to avoid any exception that might be raised if for any reason the factory has failed to create the object.

  3. Nice article. Keep up the code work.

    Below are my thoughts over the “Factory Method”;

    In a Typical scenario where the number of condition are going to be fixed.
    For Example:
    in case of Boolean outcome where the result will always either be true or false.
    So in this case we can say it for sure that there will be only two conditions.
    And we can safely use the “factory” pattern.

    While in the another scenario where the multiple branching caused due to inconsistent “if else” can be avoided using “factory method” design pattern.
    For example;
    Types of Transport
    It can be a Car,
    It can be a Truck,
    It can be an Airplane,
    It can be a Train,
    So, as we can see It can be anything. And thus our number of if else condition are unpredictable
    So, instead of adding undue branching with if else we better use “State” Design Pattern
    Or “Factory Method” Design Pattern considering the context of the situation.

    The example of card type in above article might seems like a over engineering but considering the scenario where we don’t know how many such card type will keep on coming we prefer to add the pattern. So as to keep the system extensible.

    However, care must be taken that we are not over complicating thing with design patterns .
    There are always trade offs. And we should weigh situation(context of problem) before going further with implementing pattern

  4. Charanjit singh

    Hey, you can resolve this problem just by putting the below code where i have used reflection.

    public interface ICreditCard
    {
    void Show();
    }

    public class PremiumCard : ICreditCard
    {
    private readonly double _cost;
    public PremiumCard(double cost)
    {
    this._cost =cost;
    }
    public void Show()
    {
    Console.WriteLine(“Premium Card {0}”, this._cost);
    }
    }

    public class SilverCard : ICreditCard
    {
    private readonly double _cost;
    public SilverCard(double cost)
    {
    this._cost =cost;
    }
    public void Show()
    {
    Console.WriteLine(“Silver Card {0}”, this._cost);
    }
    }

    public abstract class CreaditCardFactory
    {
    public abstract ICreditCard Create(double cost);
    }
    public class PremiumCardFactory : CreaditCardFactory
    {
    public override ICreditCard Create(double cost)
    {
    return new PremiumCard(cost);
    }
    }
    public class SilverCardFactory : CreaditCardFactory
    {
    public override ICreditCard Create(double cost)
    {
    return new SilverCard(cost);
    }
    }

    public enum CardCategories{
    PremiumCard,
    SilverCard
    }

    public class CreaditCard
    {
    private readonly CreaditCardFactory _factory;

    public CreaditCard(CardCategories type)
    {
    this._factory = (CreaditCardFactory)Activator.CreateInstance(Type.GetType(Enum.GetName(typeof(CardCategories),type) + “Factory”));
    }

    public static CreaditCard Run(CardCategories type)
    {
    return new CreaditCard(type);
    }
    public ICreditCard Execute(double cost)
    {
    return _factory.Create(cost);
    }

    }
    public class Program
    {
    public static void Main(string[] args)
    {
    var factory = CreaditCard.Run(CardCategories.PremiumCard).Execute(22.5);
    factory.Show();
    }
    }

  5. public abstract class CreditCard
    {
    public string CardType { get; set; }
    public int CardLimit { get; set; }
    public int AnnualCharge { get; set; }
    }
    public class Platinum : CreditCard
    {

    }
    public class Titanium : CreditCard
    {

    }
    public class MoneyBack : CreditCard
    {

    }

    public static class CreditCardFactory
    {
    public static CreditCard CreditCard(string selection)
    {
    var cardType = Type.GetType(“OOD.dotnetFactorytut.” + selection);
    var constructor = cardType.GetConstructor(new Type[] { });
    var creditCard = (CreditCard)constructor.Invoke(new object[] { });
    creditCard.CardType = Console.ReadLine();
    creditCard.CardLimit = int.Parse(Console.ReadLine());
    creditCard.AnnualCharge = int.Parse(Console.ReadLine());
    return creditCard;
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    bool exit = false;
    while (!exit)
    {
    Console.WriteLine();
    Console.WriteLine(“Platinum”);
    Console.WriteLine(“Titanium”);
    Console.WriteLine(“MoneyBack”);
    Console.WriteLine(“Exit”);
    Console.WriteLine();
    Console.Write(“Select demo: “);
    string choice = Console.ReadLine();
    if (choice == “Exit”)
    exit = true;
    else
    {
    var credit = CreditCardFactory.CreditCard(choice);
    Console.WriteLine($”CardType : {credit.CardType}\nCardLimit : {credit.CardLimit}\nAnnualCharge : {credit.AnnualCharge}”);
    }
    Console.WriteLine();
    Console.WriteLine(“Press ‘Enter’ for menu”);
    Console.ReadLine();
    Console.Clear();
    }
    }
    }

  6. I don’t understand, why should be have “CreateProduct()” rather direct use of “MakeProduct()” ? Could you please help me out to understand this.

  7. I am bit confused; what is the benefits of using ‘PlatinumFactory’ in-place of ‘Platinum’ concert class? as client side we have to specify each interface instance to create object!!
    in both case, any changes on concrete class there would be no change at client side code for object creation..

    Please clear my doubt

    1. RAJESHKUMAR SANKARAIAH LANKA

      I too have same question, based on user input again we need use if-else condition to call either platinum factory or titanium factory.

Leave a Reply

Your email address will not be published. Required fields are marked *