👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Creational Design Pattern - Factory

Creational Design Pattern - Factory

Author - Abdul Rahman (Bhai)

Design Pattern

13 Articles

Improve

Table of Contents

  1. What we gonna do?
  2. Why we gonna do?
  3. How we gonna do?
  4. Summary

What we gonna do?

In this article, let's learn about Factory Design Pattern in .NET.

The Factory Method is a creational pattern from the famous Gang of Four (GoF) design patterns. Creational patterns focus on object creation, and the factory method is a common approach. Its purpose is to define an interface for object creation while allowing subclasses to determine the actual type of object to instantiate.

In essence, the Factory Method allows a class to defer instantiation to subclasses, preventing tight coupling between the client and the specific implementations.

Why we gonna do?

Without the Factory Method, client code directly instantiates concrete classes, creating tight coupling. In a shopping cart system, for example, switching from a CountryDiscountService to a CodeDiscountService would require changing every place in the codebase where the service is created.

This violates the Open/Closed Principle — the system is closed for extension without modification. Adding a new discount type means modifying existing, already-tested code, increasing the risk of introducing bugs.

The Factory Method pattern solves this by moving object creation behind an abstraction, so client code depends on interfaces rather than concrete implementations. New types can be added by creating new factory subclasses without touching existing code.

How we gonna do?

Structure

The Factory pattern involves several key components:

  1. Creator: Declares the factory method that returns an object of type Product.
  2. Concrete Creator: Implements the factory method, returning an instance of a concrete product.
  3. Product: An abstract class or interface defining the object to be created.
  4. Concrete Product: The actual implementation of the product.

Imagine a shopping cart system where different discounts apply based on the user's country or discount code. Instead of the client tightly coupling to different discount services (e.g., CountryDiscountService or CodeDiscountService), we use the Factory Method pattern to abstract the creation process.


// Product
public abstract class DiscountService
{
    public abstract decimal DiscountPercentage { get; }
}

// Concrete Product 1
public class CountryDiscountService(string country) : DiscountService
{
    private readonly string _country = country;

    public override decimal DiscountPercentage =>
        _country == "India" ? 0.20m : 0.10m;
}

// Concrete Product 2
public class CodeDiscountService(string code) : DiscountService
{
    public override decimal DiscountPercentage => 0.15m;
}

// Creator
public abstract class DiscountFactory
{
    public abstract DiscountService CreateDiscountService();
}

// Concrete Creator 1
public class CountryDiscountFactory(string country) : DiscountFactory
{
    public override DiscountService CreateDiscountService()
    {
        return new CountryDiscountService(country);
    }
}

// Concrete Creator 2
public class CodeDiscountFactory(string code) : DiscountFactory
{
    public override DiscountService CreateDiscountService()
    {
        return new CodeDiscountService(code);
    }
}
            
Demo Space

From the above demo, you can see that how object creation is isolated from the client code. The client only interacts with the abstraction. In real world above Factory Pattern can be used to create different types of objects based on the user country claims or code entered by user to choose the right service to be used in shopping cart.

Use Cases

The Factory pattern is beneficial in several scenarios:

  1. When a class can't anticipate the class of objects it must create.
  2. When a class wants its subclasses to specify the objects it creates.
  3. When object creation logic might be complex, and you'd like to encapsulate it in one location.
  4. To avoid tight coupling between client code and specific classes.

Advantages

  • Loosely couples the client from concrete classes by working with interfaces or abstract classes.
  • Follows the Open/Closed Principle, allowing new product types without modifying existing code.
  • Supports the Single Responsibility Principle by centralizing object creation.

Disadvantages

  • If you only need one subclass, using the Factory Method might introduce unnecessary complexity.

The Factory pattern is closely related to several other design patterns:

  • Abstract Factory: Builds on the factory method to create families of related objects.
  • Prototype: Involves cloning objects rather than subclassing for creation.
  • Template Method: Often used in conjunction with Factory Method to handle the logic within the method.

Summary

In this article, we explored the Factory Method pattern, learning how it abstracts object creation by deferring it to subclasses. In our example, we built a discount system where the factory method determines which discount service to instantiate. This pattern prevents tight coupling and adheres to key design principles like Open/Closed and Single Responsibility.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Design Pattern
  • Creational
  • Factory