Previous GoF-Design-Pattern SOLID-principles Next

Factory Method vs Abstract Factory Pattern

Overview

Factory Method defines an interface for creating an object, but lets subclasses decide which class to instantiate. It’s used when the exact type of object isn’t known until runtime.

Abstract Factory provides an interface for creating families of related or dependent objects without specifying their concrete classes. It’s ideal when multiple related objects need to be created together.

Key Insight

In short, both patterns abstract away the complexity of object creation.

The key difference lies in how they determine which object to instantiate:

  • Factory Method uses inheritance, allowing subclasses to decide which concrete class to instantiate.
  • Abstract Factory uses delegation, providing an interface to create families of related objects without specifying their concrete classes.

In essence, Abstract Factory often builds upon Factory Method to complete its architecture. It operates at a higher level of abstraction, coordinating multiple factory methods to produce related objects consistently.

Comparison Table

Feature Factory Method Abstract Factory
Purpose Create one product Create families of related products
Flexibility Subclass decides which product to create Factory decides which family of products to create
Complexity Simple More complex
Use Case Single product with variations Multiple related products needed together
Example DocumentCreator → createDocument() UIFactory → createButton(), createMenu()

Comparison Class Diagram:

Factory and Abstract Factory class diagram

C# Example:

public abstract class Product
{
    public abstract string GetName();
}

public class ProductA : Product
{
    public override string GetName() => "Product A";
}

public class ProductB : Product
{
    public override string GetName() => "Product B";
}

public abstract class Creator
{
    public abstract Product FactoryMethod();
}

public class CreatorA : Creator
{
    public override Product FactoryMethod() => new ProductA();
}

public class CreatorB : Creator
{
    public override Product FactoryMethod() => new ProductB();
}

// Usage
Creator creator = new CreatorA();
Product product = creator.FactoryMethod();
Console.WriteLine(product.GetName()); // Output: Product A
    

Abstract Factory Pattern

C# Example:

public interface IProductA
{
    string GetName();
}

public interface IProductB
{
    string GetType();
}

public class ProductA1 : IProductA
{
    public string GetName() => "Product A1";
}

public class ProductB1 : IProductB
{
    public string GetType() => "Type B1";
}

public class ProductA2 : IProductA
{
    public string GetName() => "Product A2";
}

public class ProductB2 : IProductB
{
    public string GetType() => "Type B2";
}

public interface IAbstractFactory
{
    IProductA CreateProductA();
    IProductB CreateProductB();
}

public class ConcreteFactory1 : IAbstractFactory
{
    public IProductA CreateProductA() => new ProductA1();
    public IProductB CreateProductB() => new ProductB1();
}

public class ConcreteFactory2 : IAbstractFactory
{
    public IProductA CreateProductA() => new ProductA2();
    public IProductB CreateProductB() => new ProductB2();
}

// Usage
IAbstractFactory factory = new ConcreteFactory1();
IProductA productA = factory.CreateProductA();
IProductB productB = factory.CreateProductB();
Console.WriteLine(productA.GetName()); // Output: Product A1
Console.WriteLine(productB.GetType()); // Output: Type B1
    
Previous GoF-Design-Pattern SOLID-principles Next
*