Factory design pattern Complete guide 2019


211 Views | Read Time 7 minutes |

While taking 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,helps to resolve the common design problem in the application.

In this article, we will try to understand the Factory design pattern. Along with the use cases of factory design pattern.

Contents of the Article

  1. What is the Factory Design Pattern?
  2. UML Diagram of the Factory Design Pattern.
  3. When to use the Factory Design Pattern?
  4. Difference between factory and abstract factory pattern?
  5. Use Case of Factory Design pattern.
  6. Implementing the factory design pattern?

What is the Factory Design Pattern?

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.

UML Diagram of Factory Design Pattern

In layman term, Name of Factory Design pattern has 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 LogData.

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.

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 straight forward. Let see how we can achieve by using the factory design pattern.

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

I have created the console application for demo purposes.

Project Structure

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

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 employee 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. Its 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 piece 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.

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.


  • Recent Articles


Deependra kushwah is a member of the fastest growing bloggers community “Beetechnical”, Author, Youtuber, and hardcore developer.



Source link

WP Twitter Auto Publish Powered By : XYZScripts.com
Exit mobile version