While taking an interview if you ask any candidates, How many design patterns have you worked on? Most of the time you will get the exact same answer, singleton, and factory design pattern.

Because factory and singleton both come under the creational design pattern, it helps to resolve the common design problem in the application. In this post, we will try to understand the Factory design pattern. Along with the use cases of factory design patterns.

What is the Factory Design Pattern?

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

In the Factory pattern, we create an object without exposing the creation logic to the client and refer to a newly created object using a common interface.

Factory design pattern uml diagram
UML Diagram of Factory Design Pattern

In layman terms, the Name of the Factory Design pattern has been taken from the real word Factory. The factory takes raw material and produces different-2 products. The same approach we follow in the factory design pattern. We provide some input to the factory class and it will return the object based on the input.

Let’s understand the above UML Diagram of the Factory Design Pattern

As you can see in the above UML diagram. The client application is looking for a logger class where it can log the application data.

  • Interface: The ILogger interface has one method called log data.
  • ConcreteImplementations: TextLogger and DatabaseLogger are implementing the ILogger, to log the data in textfiles and database.
  • IFactory: The IFactory interface has one method called create.
  • FactoryMethod: The factory class will implement the Ifactory interface to perform the logic and provide the concrete implementation of ILogger based on the input from the user.
  • Client: The client class will use a factory method to get the instance of ILogger.

So, When would you use the Factory Design Pattern?

The Factory Method pattern is generally used in the following situations:

  • A different implementation of the common interface should be implemented based on user input.
  • Every implementation class has its own logic to create the object.
  • Want to hide the creation logic of object building.
  • And, while writing the API. If you don’t have the implementation of the interface.

Difference between factory and abstract factory pattern?

  • Factory: A factory that creates objects that derive from a particular base class.
  • Abstract factory: A factory that creates other factories, and these factories, in turn, create objects derived from base classes. You do this because you often don’t just want to create a single object (as with the Factory method) – rather, you want to create a collection of related objects.
Factory Design Pattern In C# | Complete Guide 2022 1
It’s time to write some code

Solve the given problem statement by using a factory design pattern

While developing an EMS system for my client, I got stuck with the situation. where I have to generate the employee based on the type of employees like permanent, contract, and freelance.

  • Permanent employee Id should start with E
  • Contract employee id should start with C
  • Freelance employee id should start with F

The requirement is pretty straightforward. Let’s see how we can achieve this by using the factory design pattern.

Let’s come up with the UML diagram, what hour implementation will look like.

Factory design pattern  Complete guide 2019,Beetechnical

I have created the console application for demo purposes.

Solution of Factory Design Pattern, Factory design pattern Complete guide 2019,Beetechnical
Project Structure

As per our UML diagram, I will create the Interface and classes. These classes and interfaces do not have any logic.

Factory Design Pattern folder structure, Factory design pattern Complete guide 2019,Beetechnical

I will start with the IEmpIdProvder interface which will have only one method called GenerateEmpId();

using FactoryDesignPatternDemo.Constants;
using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryDesignPatternDemo.Contracts
{
    public interface IEmpIdProvider
    {
        string GenerateEmpId(int empnumber);
    }
}

This interface can be implemented by a list of providers. Currently, we have only three types of employees permanent, contract, freelance. In the future, if we want to introduce one more type of employee in our system, we have to just create one more class and implement the same interface.

Provide Implementation class for PermanentEmpIdProvider

using FactoryDesignPatternDemo.Contracts;
using System;
namespace FactoryDesignPatternDemo.Impl
{
    public class PermanentEmpIdProvider : IEmpIdProvider
    {
        public string GenerateEmpId(int empnumber)
        {
            ///for demo i have hardcoded the value,
            ///you can use from configuration or database
            return "E" + empnumber;
        }
    }
}

Implementation class for ContractEmpIdProvider class.

using FactoryDesignPatternDemo.Contracts;
using System;
namespace FactoryDesignPatternDemo.Impl
{
    public class ContractEmpIdProvider : IEmpIdProvider
    {
        public string GenerateEmpId(int empnumber)
        {
            ///for demo i have hardcoded the value,
            ///you can use from configuration or database
            return "C" + empnumber;
        }
    }
}

Implementation class for FreelanceEmpIdProvider class.

using FactoryDesignPatternDemo.Contracts;
using System;
namespace FactoryDesignPatternDemo.Impl
{
    public class FreelanceEmpIdProvider : IEmpIdProvider
    {
        public string GenerateEmpId(int empnumber)
        {
            ///for demo i have hardcoded the value,
            ///you can use from configuration or database
            return "F" + empnumber;
        }
    }
}

Ok, finely we are done with the implementation of all the subclasses for EmpIdProvider. It’s time to use these classes inside the factory method and return the appropriate object based on the user’s choice.

using System;
using System.Collections.Generic;
using System.Text;
namespace FactoryDesignPatternDemo.Constants
{
    public enum EmployeeType
    {
        Permanent,
        Contract,
        Freelance
    }
}

we can use this enum to implement the factory method inside the EmpIdProviderFactory class.

As you can see in the solution explorer diagram, We have one interface for a factory provider named IEmpIdProviderFactory. This interface will only have a method that will return the IEmpIdProvider based on the enum value Employeetypes.

using FactoryDesignPatternDemo.Constants;
namespace FactoryDesignPatternDemo.Contracts
{
    public interface IEmpIdProviderFactory
    {
        IEmpIdProvider GetEmpIdProvider(EmployeeType employeeTypes);
    }
}

Implementing the factory class for IEmpIdProviderFactory.

 using FactoryDesignPatternDemo.Constants;
using FactoryDesignPatternDemo.Contracts;
namespace FactoryDesignPatternDemo.Impl
{
    public class EmpIdProviderFactory : IEmpIdProviderFactory
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="employeeTypes"></param>
        /// <returns></returns>
        public IEmpIdProvider GetEmpIdProvider(EmployeeType employeeTypes)
        {
            switch (employeeTypes)
            {
                case EmployeeType.Permanent:
                    return new PermanentEmpIdProvider();
                case EmployeeType.Contract:
                    return new ContractEmpIdProvider();
                case EmployeeType.Freelance:
                    return new FreelanceEmpIdProvider();
                default:
                    break;
            }
            return null;
        }
    }
}

As you can see in the above piece of code. We have defined the factory class which will implement the IEmpIdProvider.

Our factory implementation is ready to be consumed by the client.

Let’s add some pieces of code in the Client.cs file.

using FactoryDesignPatternDemo.Constants;
using FactoryDesignPatternDemo.Contracts;
using FactoryDesignPatternDemo.Impl;
using System;
namespace FactoryDesignPatternDemo
{
    class Client
    {
        static void Main(string[] args)
        {
            IEmpIdProviderFactory factory = new EmpIdProviderFactory();
            IEmpIdProvider empIdProvider = factory.GetEmpIdProvider(EmployeeType.Permanent);
            var permanentEmpId= empIdProvider.GenerateEmpId(1);
            Console.WriteLine("Permanent Employee Id: " + permanentEmpId);
            empIdProvider = factory.GetEmpIdProvider(EmployeeType.Freelance);
            var freelanceEmpId = empIdProvider.GenerateEmpId(1);
            Console.WriteLine("Freelance Employee Id: " + freelanceEmpId);
            empIdProvider = factory.GetEmpIdProvider(EmployeeType.Contract);
            var contractEmpId = empIdProvider.GenerateEmpId(1);
            Console.WriteLine("Contract Employee Id: " + contractEmpId);
            Console.ReadKey();
        }
    }
}

Client class just needs to create the instance of EmpIdProviderFactory which will have the logic to generate the employee Id for all employees types.

As you can see in the client.cs file. We have to just pass the enum for which type of employee you want to generate the employee Id.

Let’s see the console output of the application.

Factory Design Pattern In C# | Complete Guide 2022 2
A client using the factory method to generate the employee Id

Conclusion

So, We have seen how to implement the factory design pattern with an example. However, this is not only a way to implement the factory method. Because in this approach we are breaking the open-close principle of solid rules.

I am going to update this article to provide different ways of implementing the factory method without breaking any solid rules.

90 / 100

2 Comments

Comments are closed