Factory Method Pattern: A Flexible Object Creation Solution for Developers
Factory Method Pattern is a design pattern that allows you to create objects flexibly without knowing the exact class to instantiate. Learn how to apply this pattern for more maintainable and extensible code.

Table of Contents
No table of contents available for this article
What is Factory Method Pattern?
Factory Method (also known as Virtual Constructor) is one of the most popular design patterns in the Creational Patterns group - patterns specialized in handling object creation.
Imagine you're building a pizza delivery application. You have various pizza types: Seafood, Deluxe, Ham & Mushroom... Depending on customer choices, you need to create the corresponding pizza type. But how can you avoid writing repetitive if-else logic everywhere in your code?
Factory Method is the solution - it encapsulates object creation logic into a separate "factory."
The Problem Factory Method Solves
Real-world Scenario
Suppose you have 3 classes: Dog, Cat, Duck all implementing the IAnimal interface. When creating an animal, typical code looks like this:
IAnimal animal;
if (type == "dog") {
animal = new Dog();
} else if (type == "cat") {
animal = new Cat();
} else if (type == "duck") {
animal = new Duck();
}Problems arise when:
This logic is needed in multiple places → Code duplication
Adding a new animal (e.g.,
Rabbit) → Must modify everywhereEasy to forget updates in some places → Hidden bugs
Code becomes hard to test and maintain
How Does Factory Method Work?
Instead of creating objects directly, you call a method in the Factory class. The Factory handles deciding which object to create based on input parameters.
public class AnimalFactory {
public static IAnimal CreateAnimal(AnimalType type) {
switch (type) {
case AnimalType.Cat:
return new Cat();
case AnimalType.Dog:
return new Dog();
case AnimalType.Duck:
return new Duck();
default:
throw new ArgumentException("Invalid animal type");
}
}
}
// Usage
IAnimal animal = AnimalFactory.CreateAnimal(AnimalType.Dog);Immediate Benefits:
Object creation logic is centralized in one place
Adding new types? Only modify the Factory
Calling code becomes simpler and cleaner
Structure of Factory Method Pattern
Factory Method consists of 4 main components:
1. Product (Interface/Abstract Class)
Defines the common interface for all objects the factory creates.
public interface IPizza {
decimal GetPrice();
string GetDescription();
}2. Concrete Product (Concrete Class)
Classes that implement the Product interface with specific logic.
public class SeafoodPizza : IPizza {
public decimal GetPrice() => 11.5M;
public string GetDescription() => "Fresh seafood pizza";
}3. Creator (Factory Class)
Class containing the factory method to create Products. Can be an abstract class or interface.
public abstract class PizzaFactory {
public abstract IPizza CreatePizza();
}4. Concrete Creator
Concrete class that overrides the factory method to create corresponding Concrete Products.
public class SeafoodPizzaFactory : PizzaFactory {
public override IPizza CreatePizza() {
return new SeafoodPizza();
}
}Real-world Example with C#
Let's build a complete pizza ordering system:
// 1. Product Interface
public interface IPizza {
decimal GetPrice();
}
// 2. Concrete Products
public class HamAndMushroomPizza : IPizza {
public decimal GetPrice() => 8.5M;
}
public class DeluxePizza : IPizza {
public decimal GetPrice() => 10.5M;
}
public class SeafoodPizza : IPizza {
public decimal GetPrice() => 11.5M;
}
// 3. Factory Class
public class PizzaFactory {
public enum PizzaType {
HamMushroom,
Deluxe,
Seafood
}
public IPizza CreatePizza(PizzaType pizzaType) {
switch (pizzaType) {
case PizzaType.HamMushroom:
return new HamAndMushroomPizza();
case PizzaType.Deluxe:
return new DeluxePizza();
case PizzaType.Seafood:
return new SeafoodPizza();
default:
throw new ArgumentException($"Pizza type {pizzaType} is not supported");
}
}
}
// 4. Usage
class Program {
static void Main(string[] args) {
var factory = new PizzaFactory();
// Customer orders Seafood Pizza
IPizza pizza = factory.CreatePizza(PizzaFactory.PizzaType.Seafood);
Console.WriteLine($"Pizza price: ${pizza.GetPrice()}");
// Output: Pizza price: $11.5
}
}Advantages of Factory Method
✅ Separates object creation logic: Calling code doesn't need to know creation details
✅ Reduces coupling: Client code doesn't directly depend on concrete classes
✅ Easy to extend: Adding new products only requires creating new classes and updating the factory
✅ Improves maintainability: Logic is centralized, easier to debug and test
✅ Reduces compile errors: If you forget to declare a class, you can handle exceptions in the factory
✅ Single Responsibility Principle: Each class has only one responsibility
Disadvantages to Consider
❌ Increases complexity: Requires creating additional classes (factory, interfaces...)
❌ Over-engineering: For small, simple projects, this pattern might be overkill
❌ Difficult to refactor: Converting existing code to this pattern takes effort
❌ Private constructor: Limits inheritance capabilities of subclasses
When Should You Use Factory Method?
💡 You have multiple subclasses and need to choose which to instantiate based on conditions
💡 Object creation logic is complex and used in multiple places
💡 Want to hide implementation details from client code
💡 Plan to expand with many new product types in the future
💡 Building a library/framework where users don't need to know how objects are created
Real-world Examples:
Payment system: Choose payment gateway (PayPal, Stripe, VNPay...)
Logging system: Choose logger (FileLogger, DatabaseLogger, CloudLogger...)
Database connection: Choose driver (MySQL, PostgreSQL, SQL Server...)
Comparison: Without vs With Factory Method
❌ Without Factory Method:
// In OrderService
if (type == "seafood") pizza = new SeafoodPizza();
// In MenuService
if (type == "seafood") pizza = new SeafoodPizza();
// In InventoryService
if (type == "seafood") pizza = new SeafoodPizza();
// → Logic repeated 3 times!✅ With Factory Method:
// Everywhere uses the same approach
var pizza = PizzaFactory.CreatePizza(PizzaType.Seafood);
// → Logic in one place only, clean & maintainable!Related Design Patterns
Abstract Factory: Extension of Factory Method, creates "families" of related objects
Builder Pattern: Focuses on building complex objects step by step
Prototype Pattern: Creates new objects by cloning existing ones
Singleton + Factory: Combination to ensure only one factory instance exists
Conclusion
Factory Method Pattern is a powerful tool that makes your code flexible, maintainable, and extensible. However, consider carefully before applying it - don't let patterns add unnecessary complexity.
Golden Rule: If you find yourself copy-pasting if-else or switch-case logic to create objects in multiple places → It's time to think about Factory Method!
If you found this article helpful, explore more in the Design Patterns Series to enhance your programming skills!
References
[1] Refactoring.Guru. https://refactoring.guru/design-patterns
[2] Design Patterns for Dummies, Steve Holzner, PhD
[3] Head First Design Patterns, Eric Freeman
[4] Gang of Four Design Patterns 4.0
[5] Dive into Design Patterns