In this article, we will learn what Factory Design Pattern is and why we use Factory Design Pattern, with a real world example. We will see what type of problems are resolved using Factory Design Pattern.
Now-a-days, if we create a software, it gets outdated soon because of the requirement changes in future. So, that time, we need to write the whole logic again from scratch. The main concern when we work with Software Architecture is how to create object of entity and pass that to some other object without depending on others. One thing we need to consider is architecture should be pluggable so that in the future more objects can be added.
What Factory Design Pattern Is?
The Factory Design Pattern is a commonly used design pattern where we need to create Loosely Coupled System. Basically, it comes under Creational Pattern and it is used to create instance and reuse it. Factory Pattern is based on real time factory concept. As we know, a factory is used to manufacture something as per the requirement and if new items are added in the manufacturing process, the factory starts manufacturing those items as well. Factory class provides abstraction between Client and Car when creating the instance of the Car [Honda, BMW etc].
When to use Factory Design Pattern?
It is used for creating objects to encapsulate the instantiation logic. Client doesn’t know the actual instantiation logic of entity.
Problem
See the following example of code, where we have created two different classes as Honda and BMW. Those classes are implementing the ICarSupplier interface which has one property as CarColor and one method which provides the Car Model.
On the client side, we are simply creating the objects of two classes to get their member function and behavior.
using System;
namespace FactoryDesignPattern
{
public interface ICarSupplier
{
string CarColor { get; }
void GetCarModel();
}
class Honda : ICarSupplier
{
public string CarColor
{
get { return "RED"; }
}
public void GetCarModel()
{
Console.WriteLine("Honda Car Model is Honda 2014");
}
}
class BMW : ICarSupplier
{
public string CarColor
{
get { return "WHITE"; }
}
public void GetCarModel()
{
Console.WriteLine("BMW Car Model is BMW 2000");
}
}
class ClientProgram
{
static void Main(string[] args)
{
Honda objHonda = new Honda();
objHonda.GetCarModel();
BMW objBMW = new BMW();
objBMW.GetCarModel();
Console.ReadLine();
}
}
}
But what is the problem with this code? Just think, if in the future, a new Car [Nano] is introduced and the client has to create an instance of that class to access all the property and member function, they need to modify the object creation logic and add the following code.
Nano is a new class which also implements ICarSupplier.
class Nano : ICarSupplier
{
public string CarColor
{
get { return "YELLOW"; }
}
public void GetCarModel()
{
Console.WriteLine("Nano Car Model is Nano 2016");
}
}
Instantiation of Nano class.
Nano objNano = new Nano();
objNano.GetCarModel();
We can do that if we add new class, we need to modify the instantiation logic at client, as above code shown. The biggest problem is that we don't know how many entities are going to add in future. If new car is added, then we need to write the logic at client end to access that class properties and methods. So, we need to add a Factory which will give you the instance at runtime.
Solution
So, in Factory Design Pattern, there we will add a Factory class where we can add a method which will return the instance of the class based on your requirement. We can see with the following code where GetCarInstance method takes one argument as Id.
On the basis of the Id, it will return the instance of the Car. As per example, if client passes 0, then it will return the instance of the Honda Car, if they pass 1, then it will return the instance of BMW car.
static class CarFactory
{
public static ICarSupplier GetCarInstance(int Id)
{
switch (Id)
{
case 0:
return new Honda();
case 1:
return new BMW();
case 2:
return new Nano();
default:
return null;
}
}
}
In future, if a new car is launched e.g. Suzuki, there is no need to add anything on the client side. You just need to add one case for Suzuki to get the instance.
Case. 3
return new Suzuki();
And, just pass the id=3 when creating the object of CarFactory class. Just notice with following code, we are passing 3 inside the GetCarInstance and as we have defined in CarFactory, it will return the instance of the Suzuki Car.
ICarSupplier objCarSupplier = CarFactory.GetCarInstance(3);
objCarSupplier.GetCarModel();
Console.WriteLine("And Color is " + objCarSupplier.CarColor);
Following is the whole code for demonstration of Factory Design Pattern which will give us an idea of how and where we should implement Factory Design Pattern in Real Life.
using System;
namespace FactoryDesignPattern
{
public interface ICarSupplier
{
string CarColor { get; }
void GetCarModel();
}
class Honda : ICarSupplier
{
public string CarColor
{
get { return "RED"; }
}
public void GetCarModel()
{
Console.WriteLine("Honda Car Model is Honda 2014");
}
}
class BMW : ICarSupplier
{
public string CarColor
{
get { return "WHITE"; }
}
public void GetCarModel()
{
Console.WriteLine("BMW Car Model is BMW 2000");
}
}
class Nano : ICarSupplier
{
public string CarColor
{
get { return "YELLOW"; }
}
public void GetCarModel()
{
Console.WriteLine("Nano Car Model is Nano 2016");
}
}
class Suzuki : ICarSupplier
{
public string CarColor
{
get { return "Orange"; }
}
public void GetCarModel()
{
Console.WriteLine("Suzuki Car Model is Suzuki 2006");
}
}
static class CarFactory
{
public static ICarSupplier GetCarInstance(int Id)
{
switch (Id)
{
case 0:
return new Honda();
case 1:
return new BMW();
case 2:
return new Nano();
case 3:
return new Suzuki();
default:
return null;
}
}
}
class ClientProgram
{
static void Main(string[] args)
{
ICarSupplier objCarSupplier = CarFactory.GetCarInstance(3);
objCarSupplier.GetCarModel();
Console.WriteLine("And Color is " + objCarSupplier.CarColor);
Console.ReadLine();
}
}
}
Conclusion
So, today we learned what Factory Design Pattern is and why and where it can be used, with real world examples.
I hope this post will help you. Please put your feedback in the comment box which helps me improve myself for my next posts.