Why We need Factory Design Pattern?

Factory Design Pattern

Category: It comes under the Creational Design Pattern.

What is the problem/state before using the above pattern?

There is a tight coupling between the Client class and Object creation logic. If we want to add another type of object then we need to add code in client class.

Why do we need it?

It decouples client class & object/product creation logic. It moves object creation logic in the factory class.

Components of Factory Pattern

  1. Client: It is a class. It requests objects from the factory.
  2. Factory: It is a class. It has a method to create other objects. It is responsible for giving objects requested by the client.
  3. Abstract Product: It is an interface or abstract class. It defines common characteristics of the product or object to be created.
  4. Concrete Product: This is a class. It provides specific implementation details of abstract products & creating products.

Benefits

  1. Decoupling: The Factory Design Pattern helps decouple object creation from the specific class of object being created. This makes it easier to change or replace the concrete class without affecting the rest of the system.
  2. Polymorphism: The Factory Design Pattern enables polymorphism by allowing you to treat different types of objects in a uniform way. You can work with objects of different classes without knowing their specific class type.
  3. Encapsulation: The Factory Design Pattern encapsulates the logic for creating objects within the factory class. This helps hide the complexity of object creation from the client code.
  4. Reusability: The Factory Design Pattern promotes reusability by allowing you to create multiple objects of different classes using the same factory.
  5. Flexibility: The Factory Design Pattern makes it easy to add new concrete classes without modifying the existing code. You can simply add a new case to the factory's creation logic.
  6. Testability: The Factory Design Pattern makes it easier to write unit tests by allowing you to mock or stub the factory to return specific objects for testing.

Let us see an example,

We have one Phone factory that creates Feature Phones, Flip Phone & Smart Phone.

Defining phone interface

using System;

// Product interface
public interface IPhone
{
    string Type { get; }
    string Display { get; }
    string Keyboard { get; }
}

We create concrete phone classes (FeaturePhone, FlipPhone, SmartPhone) that implement the IPhone interface.

// Concrete Products
public class FeaturePhone : IPhone
{
    public string Type => "Feature Phone";
    public string Display => "Small Color Display";
    public string Keyboard => "Numeric Keypad";
}

public class FlipPhone : IPhone
{
    public string Type => "Flip Phone";
    public string Display => "Small Color Display";
    public string Keyboard => "Numeric Keypad with Flip Design";
}

public class SmartPhone : IPhone
{
    public string Type => "Smart Phone";
    public string Display => "Large Touchscreen Display";
    public string Keyboard => "Virtual Keyboard";
}

We define a PhoneFactory class that creates instances of phone classes based on the phone type.

// Factory
public class PhoneFactory
{
    public static IPhone CreatePhone(string phoneType)
    {
        switch (phoneType)
        {
            case "FeaturePhone":
                return new FeaturePhone();
            case "FlipPhone":
                return new FlipPhone();
            case "SmartPhone":
                return new SmartPhone();
            default:
                throw new ArgumentException("Invalid phone type");
        }
    }
}

Program class is a Client Class. In the Main method, we use the PhoneFactory to create phones.

class Program
{
    static void Main(string[] args)
    {
        IPhone featurePhone = PhoneFactory.CreatePhone("FeaturePhone");
        Console.WriteLine("Type: " + featurePhone.Type);
        Console.WriteLine("Keyboard: "+ featurePhone.Keyboard);
        Console.WriteLine("Display: "+featurePhone.Display);

        Console.WriteLine("------------");

        IPhone flipPhone = PhoneFactory.CreatePhone("FlipPhone");
        Console.WriteLine("Type: " + flipPhone.Type);
        Console.WriteLine("Keyboard: "+ flipPhone.Keyboard);
        Console.WriteLine("Display: "+flipPhone.Display);

    }
}

Output is shown below.

Output

Thank you. You have mastered the Factory pattern.