Factory Design Pattern in C#

Factory Design Pattern in C# with Examples

In this article, I am going to discuss the Factory Design Pattern in C# with an example. The Factory Design Pattern in C# is one of the most frequently used design pattern in real-time applications. Before going to understand the factory design pattern in C#, let us first discuss what exactly a factory is from a Lehman’s point of view.

From Lehman’s point of view, we can say that a factory is a place where products are created. In order words, we can also say that it is a centralized place for creating products. Later, based on the order is received, the appropriate product is delivered by the factory.

For example, a car factory can produce different types of cars. If you are ordering a car to the car factory, then based on your requirements or specifications, the factory will create the appropriate car and then delivered that car to you.

The same thing has also happened in the factory design pattern in C#. A factory (it’s a class) which will create and deliver products (i.e. objects) based on the incoming parameters.

Types of factory pattern in C#.

We can implement the factory pattern in C# in three different ways. They are as follows

  1. Simple Factory Design Pattern
  2. Factory Method Design Pattern
  3. Abstract Factory Design Pattern

Note: In this article, we are going to discuss how to implement the Simple Factory Design Pattern in C# with an example.

What is the Simple Factory Design Pattern in C#?

The definition of Simple Factory Design Pattern states that “A factory is an object which is used for creating other objects”. In technical terms, we can say that a factory is a class with a method. That method will create and return different types of objects based on the input parameter is received.

Let us understand the Factory Design Pattern in C# with an example.

We are going to develop an application for showing the credit card details. In the following example, we have three types of credit card such as MoneyBack, Titanium, and Platinum. Then we will ask the user to select the credit card type. Once the user selects the card type then we need to display the card information of that selected card.

Let us first discuss how to achieve this without using the Factory Design Pattern in C#. Then we will discuss the problems and finally, we will create the same application using the Factory Design Pattern.

Without using Factory Design Pattern in C#

Here we need to create either an interface or an abstract class which will create the signature of the operations a credit card should have. So, create an interface with the name ICreditCard and then copy and paste the following code in it.

namespace FactoryPattern
{
    public interface ICreditCard
    {
        string GetCardType();
        int GetCreditLimit();
        int GetAnnualCharge();
    }
}

As you can see, we created the interface with three methods. Now we need to create three Product classes which will implement the above interface. So create a class file with the name MoneyBackCreditCard.cs and then copy and paste the following code in it.

namespace FactoryPattern
{
    public class MoneyBackCreditCard : ICreditCard
    {
        public string GetCardType()
        {
            return "MoneyBack";
        }

        public int GetCreditLimit()
        {
            return 15000;
        }

        public int GetAnnualCharge()
        {
            return 500;
        }
    }
}

Similarly create another class file with the name TitaniumCreditCard.cs and then copy and paste the following code in it.

namespace FactoryPattern
{
    public class TitaniumCreditCard : ICreditCard
    {
        public string GetCardType()
        {
            return "Titanium";
        }

        public int GetCreditLimit()
        {
            return 25000;
        }

        public int GetAnnualCharge()
        {
            return 1500;
        }
    }
}

Finally, create another class file with the name PlatinumCreditCard.cs and then copy and paste the following code in it.

namespace FactoryPattern
{
    public class PlatinumCreditCard : ICreditCard
    {
        public string GetCardType()
        {
            return "Platinum";
        }

        public int GetCreditLimit()
        {
            return 35000;
        }

        public int GetAnnualCharge()
        {
            return 2000;
        }
    }
}
Implementing the Client Code:

Now we need to ask the user to select the Credit Card Type. Then we need to create an instance of any one of the above three product implementation class. So modify the Program class Main method as shown below.

namespace FactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //Generally you will get the Card Type from UI.
            //Here we are hardcoded the card type
            int cardType = 2;

            ICreditCard cardDetails = null;

            //Based of the Card Type we are creating the
            //appropriate type instance using if else condition
            if (cardType == 1)
            {
                cardDetails = new MoneyBackCreditCard();
            }
            else if (cardType == 2)
            {
                cardDetails = new TitaniumCreditCard();
            }
            else if (cardType == 3)
            {
                cardDetails = new PlatinumCreditCard();
            }

            if (cardDetails != null)
            {
                Console.WriteLine("CardType : " + cardDetails.GetCardType());
                Console.WriteLine("CreditLimit : " + cardDetails.GetCreditLimit());
                Console.WriteLine("AnnualCharge :" + cardDetails.GetAnnualCharge());
            }
            else
            {
                Console.Write("Invalid Card Type");
            }

            Console.ReadLine();
        }
    }  
}

The above code implementation of the Main method is straightforward. Once we get the CardType value, then by using if else condition we are creating the appropriate Credit Card Type instance. Then we are just calling the three methods to display the credit card information in the console window. So, when we run the application, we get the output as expected as shown below.

Factory Design Pattern in C#

The above code implementation introduces the following problems

  1. First, the tight coupling between program class (i.e. the client class) and Product Class such as MoneyBackCreditCard, TitaniumCreditCard, and PlatinumCreditCard.
  2. Secondly, if we add new Card type, then we also need to modify the Main method of the program class by adding extra if else condition which not only overheads in the development but also in the testing process

Let us see how to overcome the above problem by using a simple factory design pattern.

Simple Factory Design Pattern in C#:

The factory Design pattern in C# deals with the problem of creating objects (i.e. Products in our case object of MoneyBackCreditCard, TitaniumCreditCard, and PlatinumCreditCard class) without exposing the exact class name to the client. Then the client can refer to the newly created object through a common interface. So the client uses the factory to create the products which are shown in the below image.

Factory Design Pattern in C#

Creating the Factory Class:

Create a class with the Name CardFactory.cs and then copy and paste the following code in it. This is going to be our factory class which will create and return the instance.

namespace FactoryPattern
{
    public class CardFactory
    {
        public static ICreditCard GetCardInstance(int cardType)
        {
            ICreditCard cardDetails = null;

            if (cardType == 1)
            {
                cardDetails = new MoneyBackCreditCard();
            }
            else if (cardType == 2)
            {
                cardDetails = new TitaniumCreditCard();
            }
            else if (cardType == 3)
            {
                cardDetails = new PlatinumCreditCard();
            }

            return cardDetails;
        }
    }
}

As you can see the above code is very straightforward. The CardFactory class has a static GetCardInstance method. This method takes the Card Type as an input parameter and then creates the appropriate credit card instance and returns that instance. Now let us see how this factory is going to be used by the client. In our example, the client is nothing but the program class.

Modifying the Program class to use factory Design Pattern:

namespace FactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            int cardType = 2;

            //Getting the instance from the factory class
            ICreditCard cardDetails = CardFactory.GetCardInstance(cardType);

            if (cardDetails != null)
            {
                Console.WriteLine("CardType : " + cardDetails.GetCardType());
                Console.WriteLine("CreditLimit : " + cardDetails.GetCreditLimit());
                Console.WriteLine("AnnualCharge :" + cardDetails.GetAnnualCharge());
            }
            else
            {
                Console.Write("Invalid Card Type");
            }

            Console.ReadLine();
        }
    }  
}

Now run the application and you will see the output as expected.

Where to Use factory Design Pattern?

It would not be a good programming approach to specify the exact class name while creating the objects by the client. To overcome this problem, we need to use the Factory Design Pattern in C#. This design pattern provides the client with a simple mechanism to create the object. So, we need to use the Factory Design Pattern in C# when

  1. The Object needs to be extended to the subclasses
  2. Classes don’t know what exact sub-classes it has to create
  3. The Product implementation going to change over time and the Client remains unchanged
Advantages of Simple Factory Design Pattern in C#
  1. It’s very easy to implement
  2. The Client code remains unchanged when we add new products.
  3. The client does now know what subclasses it is using.
Disadvantages of Simple Factory Design Pattern in C#
  1. If we need to add any new product (i.e. new credit card type) then we need to a new if else condition in the GetCardInstance method of the CardFactory class. This violates the open/closed design principle.
  2. We also have a tight coupling between the Factory (CardFactory) class and products classes (MoneyBackCreditCard, TitaniumCreditCard, and PlatinumCreditCard).

In the next article, I am going to discuss how to overcome the above problem by using the factory method design pattern in C#.

SUMMARY

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

Leave a Reply

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