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 Examples. 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 Design 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 the Gang of Four, the Factory Method Design Pattern States that Defines an interface for creating an object, but lets the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.

Let us simplify the above definition. The Factory Method Design Pattern is used, when we need to create the object (i.e. an 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.

Example to Understand Factory Method Design Pattern in C#:

Let us understand the Factory Method Design Pattern with one real-time example using C#. We are going to develop an application for showing credit card information. This is the same example that we discussed in our previous article, but here instead of Factory Design Pattern, we are going to use the Factory Method Design Pattern.

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 (which we can also call Abstract Product). 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) i.e. the Product classes.

Example to Understand Factory Method Design Pattern in C#

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 Abstract Creator Class that declares the Factory Method i.e. CreateProduct() which will return an object of type Product via the abstract product type i.e. CreditCard. The CreditCardFactory Creator class declares the factory method i.e. MakeProduct() that is going to return an object of a Product class. The CreditCardFactory subclasses usually provide the implementation of the MakeProduct method.

What is Factory Method Design Pattern?

As you can see, the above abstract class (i.e. CreditCardFactory) contains two methods, one abstract method i.e. MakeProduct() which is going to be our Factory method, 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) by implementing the Abstract CreditCradFactory class and providing implementation to the MakeProduct abstract method. This method is going to return the actual product object i.e. (MoneyBack, Platinum, and Titanium) via the product interface type i.e. CreditCard.

Implementing the Factory Method Design Pattern in C#

Now let’s see how the client is going to consume the above CreditCardFactory to create an object. Please have a look at the following diagram. The client code works with an instance of a concrete creator i.e. the classes which implement the CreditCardFactory abstract class. The CreateProduct method will return the actual product object via the abstract Product interface type i.e. Creditcard.

When to use Factory Method Design Pattern in C#?

As shown in the above image, the client wants to create a Platinum object. In order to do so, the clients call the CreateProduct method on the PlatinumFactory instance which will return a concrete Platinum object via the CreditCard type. Similarly, if the client wants to create a Titanium object, then the client needs to call the CreateProduct method on the Titanium Factory instance which will return a concrete Titanium object.

Implementing the Factory Method Design Pattern in C#:

Now, let us proceed and implement the example step by step by using the Factory Method Design Pattern in C#.

Step 1: Creating Product Interface (CreditCard)

Create a class file with the name CreditCard.cs and then copy and paste the following code into it. 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
{
    // The CreditCard interface declares the operations that all 
    // concrete products must implement.
    public interface CreditCard
    {
        string GetCardType();
        int GetCreditLimit();
        int GetAnnualCharge();
    }
}
Step 2: Creating Concrete Products (MoneyBack, Titanium, and Platinum)

This is a class implementing the Product interface (CreditCard) and providing implementation to the interface methods. 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.

MoneyBack.cs

Create a class file with the name MoneyBack.cs and then copy and paste the following code into it.

namespace FactoryMethodDesignPattern
{
    // MoneyBack Product provides implementations of the CreditCard interface methods.
    public class MoneyBack : CreditCard
    {
        public string GetCardType()
        {
            return "MoneyBack";
        }
        public int GetCreditLimit()
        {
            return 15000;
        }
        public int GetAnnualCharge()
        {
            return 500;
        }
    }
}
Titanium.cs:

Create a class file with the name Titanium.cs and then copy and paste the following code into it.

namespace FactoryMethodDesignPattern
{
    //Titanium Product provides implementations of the CreditCard interface methods.
    public class Titanium : CreditCard
    {
        public string GetCardType()
        {
            return "Titanium Edge";
        }
        public int GetCreditLimit()
        {
            return 25000;
        }
        public int GetAnnualCharge()
        {
            return 1500;
        }
    }
}
Platinum.cs:

Create a class file with the name Platinum.cs and then copy and paste the following code into it.

namespace FactoryMethodDesignPattern
{
    //Platinum Product provides implementations of the CreditCard interface methods.
    public class Platinum : CreditCard
    {
        public string GetCardType()
        {
            return "Platinum Plus";
        }
        public int GetCreditLimit()
        {
            return 35000;
        }
        public int GetAnnualCharge()
        {
            return 2000;
        }
    }
}
Step 3: Creating Abstract Creator (CreditCardFactory)

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. The following class code is self-explained, so please go through the comment lines for a better understanding.

namespace FactoryMethodDesignPattern
{
    // The CreditCardFactory Creator class declares the factory method 
    // that is going to return an object of a Product class. 
    // The CreditCardFactory subclasses usually provide the implementation of the MakeProduct method.
    public abstract class CreditCardFactory
    {
        protected abstract CreditCard MakeProduct();

        // Also note that The Creator's primary responsibility is not creating products. 
        // Usually, it contains some core business logic that relies on Product objects, returned by the factory method. 
        public CreditCard CreateProduct()
        {
            //Call the MakeProduct which will create and return the appropriate object 
            CreditCard creditCard = this.MakeProduct();
            //Return the Object to the Client
            return creditCard;
        }
    }
}

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. The MakeProduct() is going to be implemented by the concrete creator classes i.e. the sub-classes of the abstract creator class i.e. CreditCardFactory.

Step 4: Creating Concrete Creator (PlatinumFactory, MoneyBackFactory, and TitaniumFactory)

The Concrete Creator class implements the Abstract Creator class and overrides the factory method. The override Factory Method is going to return an instance of a Concrete Product via the base Product interface. As we have three types of Credit Cards, we are going to create three Concrete Creator classes i.e. PlatinumFactory, MoneyBackFactory, and TitaniumFactory which will implement the abstract Creator Class i.e. CreditCardFactory class.

PlatinumFactory Concrete Creator

So, create a class file with the name PlatinumFactory.cs and then copy and paste the following code into it. The following code is self-explained, so please go through the comment lines for a better understanding.

namespace FactoryMethodDesignPattern
{
    // PlatinumFactory Concrete Creators override the factory MakeProduct method
    // to create and return the Platinum Product
    public class PlatinumFactory : CreditCardFactory
    {
        // The signature of the method uses the abstract product CreditCard type,
        // Even though the concrete Platinum product is returned from the method.
        // This way the Abstract Creator CreditCardFactory can stay independent of concrete product classes.
        protected override CreditCard MakeProduct()
        {
            CreditCard product = new Platinum();
            return product;
        }
    }
}
MoneyBackFactory Concrete Creator

So, create a class file with the name MoneyBackFactory.cs and then copy and paste the following code into it. The following code is self-explained, so please go through the comment lines for a better understanding.

namespace FactoryMethodDesignPattern
{
    // MoneyBackFactory Concrete Creators override the factory MakeProduct method
    // to create and return the MoneyBack Product
    public class MoneyBackFactory : CreditCardFactory
    {
        // The signature of the method still uses the abstract product CreditCard type
        // Even though the concrete MoneyBack product is actually returned from the method.
        // This way the Creator can stay independent of concrete product classes.
        protected override CreditCard MakeProduct()
        {
            CreditCard product = new MoneyBack();
            return product;
        }
    }
}
TitaniumFactory Concrete Creator

So, create a class file with the name TitaniumFactory.cs and then copy and paste the following code into it. The following code is self-explained, so please go through the comment lines for a better understanding.

namespace FactoryMethodDesignPattern
{
    // TitaniumFactory Concrete Creators override the factory MakeProduct method
    // to create and return the Platinum Product
    public class TitaniumFactory : CreditCardFactory
    {
        // The signature of the method uses the abstract product CreditCard type,
        // Even though the concrete Titanium product is returned from the method.
        // This way the Abstract Creator CreditCardFactory can stay independent of concrete product classes.
        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 says 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.

Step 5: Consuming the Factory Method in the Client Code:

The client code works with an instance of a concrete creator i.e. we need to create an instance of either PlatinumFactory, MoneyBackFactory, or TitaniumFactory. Then on the concrete creator instance, we need to call the CreateProduct method which will return the actual product instance via the product interface i.e. CreditCard type.

If you want to create an instance of the Platinum CreditCard then call the CreateProduct method on 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 of the Program class as follows.

using System;
namespace FactoryMethodDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // The client code works with an instance of a concrete creator
            // The CreateProduct will return the actual product instance via the product interface

            //PlatinumFactory CreateProduct method will return an instance of Platinum Product via the CreditCard interface
            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("--------------");
            //MoneyBackFactory CreateProduct method will return an instance of Platinum Product via the CreditCard interface
            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 in the below image.

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

Factory Method Design Pattern UML (Class) Diagram:

Once we understand how to implement the Factory Method Design Pattern in C#, let us try to understand the UML (Unified Modeling Language) or Class diagram of the Factory Method Design Pattern. For a better understanding, please have a look at the following diagram which shows the different components of the Factory Method Design Pattern. Here, I am comparing the Factory Method Design Pattern UML diagram with our CreditCard example, so that you can easily understand the different components of the Factory Method Design Pattern.

Factory Method Design Pattern UML (Class) Diagram

Let us understand each component of the Factory Method Design Pattern:

  1. Product: This is an interface for creating objects. Here, we need to define the Opeartions a Product should have. In our example, it is the CreditCard interface.
  2. Concrete Product: This is a class that implements the Product interface. In our example, MoneyBack, Titanium, and Platinum classes are the Concrete Products. These classes implement the Product interface i.e. CreditCard.
  3. Abstract Creator: This is an abstract class and declares the factory method, which returns an object of type Product. In our example, it is the CreditCardFactory abstract class and this class has the CreateProduct Factory method which will create and return an instance of the actual product. Internally, this CreateProduct method will call the subclass MakeProduct method which will actually create and return the appropriate product instance.
  4. Concrete Creator: These are the classes that implement the Abstract Creator class and override the factory method to return an instance of a Concrete Product.

In the next article, I am going to discuss the Abstract Factory Design Pattern in C# with Examples. 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 Factory Method Design Pattern in C# with Examples article.

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

  1. blank

    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. blank

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

    2. blank

      My best guess would be the following:
      With the Factory Method, we can now take an input (eg from the user) which will give the client the type of factory to be used. This way we can controll where the changes are made in case it will be needed in the future. If we’re just doing:
      CreditCard creditcard = new MoneyBack();
      We’re basically enforcing the client to unneccesarily depend on something (in this case the MoneyBack class) which might change in the future and thereby require changes in the client. Think of using a class variable instead of encapsulating it in a property.

      If this is actually the case, then the following statement is a bit misleading:
      CreditCard creditCard = new PlatinumFactory().CreateProduct();

      A better example would if so be:
      CreditCardFactory UserSelectedFactory = ReadInputFromUser(); // Read in the desired factory
      CreditCard creditCard = UserSelectedFactory.CreateProduct(); // Create the desired product

      Now we have a structured place to add, create and change products, without touching the client. It allows us to follow the open/close principle for the abstract factory and product interface, and it creates a local place in the code for potential changes in the future.

      Then again, I can’t say I know this for sure. In the book, there’s a lot more to this design pattern than covered by the post. There they eg put more emphasis that this design pattern is meant to put the “type” of objects to be created in the hands of the subclass-Factory (eg PlatinumFactory). Which is also defined by the authors: “… let the subclasses decide which class to instantiate …”, so the PlatinumFactory should decide the class to be created. The example in the post doesn’t make this obvious as it only shows each factory to handling a single class each.

      Say the PlatinumFactory can also create different CreditCard classes (they have PlatinumPremium, PlatinumPlus, PlatinumBasic etc..), then it’s up to PlatinumFactory to define these classes, and also how these classes will be selected. Perhaps the factory method takes a parameter: CreateCreditCard(paymentPlan) which will decide what type of Platinum card should be instantiated. The abstract CreditCardfactory here is oblivious to the type being created, it just knows that an ICreditCard should be instantiated.

      I don’t know if this rant made things clearer or not, but it gave me some clarity to write it out, so if you made it to the end and realized I don’t know what I’m talking about..
      ..I’m sorry to have wasted your time q(‘c’)p

    3. blank

      It is written that “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.”
      Although there is no more logic to create new instances in this example, you can use this pattern when the creation required some info that you don’t want to expose.

  2. blank

    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. blank

    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. blank
    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. blank

    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. blank

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

  7. blank

    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. blank
      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.

  8. blank

    I think in the Simple Factory Method we had a different scenario which based on a string value that was card type, we were trying to choose which concrete class should be created. but if we want to apply the factory method to the same example, again we need if-else to choose which factory class we use to create the object and we just create more complexity. yes, the pattern is not violating solid principles inside factory class but I think it is only useful when we exactly know which type we need and not based on a condition. so I believe It just adds more complexity.

  9. blank

    Can you explain why don’t make the MakeProduct() as public abstract, then just call this instead of call CreateProduct() indirectly?

    Thanks,
    Eric

  10. blank

    MakeProduct() and CreateProduct() both does same thing. Since we are calling the MakeProduct() in CreateProduct().
    and the Object creation logic is in the MakeProduct() and implementation of that is present in the ConcreteCreator.cs (i.e class which is used for the creation of the Object).
    So, In the ConcreteCreator.cs Method we are overriding the MakeProduct() method because the method says that we are making here.
    and in the client method, the article writer may have thought it is not readable to use the method MakeProduct() for user understanding. so, he used CreateProduct() which does the same.
    that is just for better understanding for the developer. I believe!
    There is no issue in calling the same method MakeProduct() everywhere. it is just to make sure user understandable

  11. blank

    PlatinumFactory().CreateProduct()
    This is code from main()
    If new credit card added then we need to change client code?

    Is it proper?
    In my opinion factory design pattern is better where in case of new credit card added then change will be in credit card interface only

  12. blank

    In this example also, we have to change the code in client side if one more Card type come into the picture….. Then what is the benefit of using this in place of factory pattern?

  13. blank

    An example of using this design template is in a table when you want to create a new row – the new row must be the same as the table associated with it – therefore we would like the person who creates it – to always be from a table

    Also – this design template is suitable when we also want the created classes of credit cards to be divided according to different types for each subtype

    Also – the advantage of the method that does not accept parameters to create – gives us more flexibility in that each type of card can decide for itself which type to produce by its unique characteristics

    Another use of this template – when we want, for example, that every time an instance of a credit card is produced in the system – then another class in the program is updated or produced as well

Leave a Reply

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