Low Level Design

Abstract Factory Pattern — Families of Related Objects in Java

How the Abstract Factory pattern ensures product families stay consistent and eliminates the risk of mixing incompatible objects at compile time.

August 26, 2026·10 min read

What is the Abstract Factory Pattern?#

The Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes.

It's a factory of factories — each concrete factory creates a complete, internally consistent product family.

You reach for Abstract Factory when:

  • You need to create families of related objects that must be used together
  • You want to ensure products from the same family are always compatible
  • You need to switch between entire product lines at runtime (e.g., different UI themes, cloud providers, restaurant chains)

Real-World Analogy#

Think of pizza restaurant chains — Domino's, Pizza Hut, and Brik Oven. Each chain is its own abstract factory that produces a complete family of pizza products. When you order at Domino's, you get their specific base, sauce, and cheese — all designed to work together.

You can't mix Pizza Hut's base with Domino's sauce and expect a consistent result. The abstract factory enforces that consistency.


Class Diagram#


Violation Code — The Problem#

Without Abstract Factory, client code directly instantiates concrete products and can accidentally mix families:

java
class BadPizzaStore {
    void makeMixedPizza() {
        // ❌ Mixing Dominos pizza with Pizza Hut sauce — incoherent!
        DominosMargheritaPizza pizza = new DominosMargheritaPizza();
        PizzaHutTomatoSauce sauce = new PizzaHutTomatoSauce();
        DominosMozzarella cheese = new DominosMozzarella();

        pizza.prepare();
        sauce.addSauce();
        cheese.addCheese();
    }
}

Issues:

  1. No family consistency — nothing prevents mixing incompatible products
  2. Tight coupling — client depends on every concrete class
  3. Violates OCP — adding a new chain (Brik Oven) requires modifying the client
  4. Code duplication — creation logic repeated across many places
  5. Type safety — easy to accidentally combine the wrong products

Enhanced Code — Abstract Factory#

java
// Abstract product interfaces
interface Pizza  { void prepare();  }
interface Sauce  { void addSauce(); }
interface Cheese { void addCheese();}

// Domino's product family
class DominosMargheritaPizza implements Pizza {
    public void prepare() { System.out.println("Dominos: thin crust margherita"); }
}
class DominosTomatoSauce implements Sauce {
    public void addSauce() { System.out.println("Dominos: tangy tomato sauce"); }
}
class DominosMozzarella implements Cheese {
    public void addCheese() { System.out.println("Dominos: mozzarella"); }
}

// Pizza Hut product family
class PizzaHutMargheritaPizza implements Pizza {
    public void prepare() { System.out.println("Pizza Hut: pan crust margherita"); }
}
class PizzaHutTomatoSauce implements Sauce {
    public void addSauce() { System.out.println("Pizza Hut: rich tomato sauce"); }
}
class PizzaHutMozzarella implements Cheese {
    public void addCheese() { System.out.println("Pizza Hut: blend cheese"); }
}

// Abstract factory interface
interface PizzaFactory {
    Pizza  createPizza();
    Sauce  createSauce();
    Cheese createCheese();
}

// Concrete factories — each guarantees a consistent family
class DominosPizzaFactory implements PizzaFactory {
    public Pizza  createPizza()  { return new DominosMargheritaPizza(); }
    public Sauce  createSauce()  { return new DominosTomatoSauce(); }
    public Cheese createCheese() { return new DominosMozzarella(); }
}

class PizzaHutPizzaFactory implements PizzaFactory {
    public Pizza  createPizza()  { return new PizzaHutMargheritaPizza(); }
    public Sauce  createSauce()  { return new PizzaHutTomatoSauce(); }
    public Cheese createCheese() { return new PizzaHutMozzarella(); }
}

// Client — decoupled from all concrete types
class PizzaStore {
    private final PizzaFactory factory;

    PizzaStore(PizzaFactory factory) { this.factory = factory; }

    void makePizza() {
        Pizza  pizza  = factory.createPizza();
        Sauce  sauce  = factory.createSauce();
        Cheese cheese = factory.createCheese();
        pizza.prepare();
        sauce.addSauce();
        cheese.addCheese();
    }
}

// Usage
class Main {
    public static void main(String[] args) {
        PizzaStore dominosStore   = new PizzaStore(new DominosPizzaFactory());
        PizzaStore pizzaHutStore  = new PizzaStore(new PizzaHutPizzaFactory());

        dominosStore.makePizza();
        pizzaHutStore.makePizza();
    }
}

Adding Brik Oven requires only: one new BrikOvenPizzaFactory class plus three product classes — zero changes to PizzaStore.


Common LLD Problems Using Abstract Factory#

1. Cross-Platform UI Toolkit#

  • Abstract Factory: WidgetFactory
  • Products: Button, Checkbox, TextField
  • Variants: MacWidgetFactory, WindowsWidgetFactory, LinuxWidgetFactory

2. Theme-Based UI System (Dark / Light Mode)#

  • Abstract Factory: UIThemeFactory
  • Products: ThemedButton, ThemedNavbar, ThemedCard
  • Variants: DarkThemeFactory, LightThemeFactory

3. Cloud Infrastructure Provisioning#

  • Abstract Factory: CloudResourceFactory
  • Products: Compute, Storage, Database
  • Variants: AWSFactory, AzureFactory, GCPFactory

4. Game Environment Generator#

  • Abstract Factory: GameEnvironmentFactory
  • Products: Enemy, Terrain, NPC
  • Variants: DesertWorldFactory, SnowWorldFactory, ForestWorldFactory

5. Car Manufacturing#

  • Abstract Factory: CarPartsFactory
  • Products: Engine, Tyre, Suspension
  • Variants: LuxuryCarPartsFactory, SportsCarPartsFactory

6. OS-Specific Driver Loader#

  • Abstract Factory: DriverFactory
  • Products: KeyboardDriver, MouseDriver, PrinterDriver
  • Variants: WindowsDriverFactory, LinuxDriverFactory, MacDriverFactory

7. Cross-Device Media Renderer#

  • Abstract Factory: MediaRendererFactory
  • Products: VideoPlayer, AudioPlayer, SubtitleRenderer
  • Variants: MobileRendererFactory, DesktopRendererFactory, SmartTVRendererFactory

8. OS-Specific File System API#

  • Abstract Factory: FileSystemFactory
  • Products: File, Directory, PathResolver
  • Variants: UnixFileSystemFactory, WindowsFileSystemFactory

Factory vs Abstract Factory#

Factory MethodAbstract Factory
CreatesOne productA family of related products
GuaranteesSingle object typeFamily consistency
Use whenYou need one thingProducts must work together

ReferencesLinks
Article ReferenceRefactoring Guru — Abstract Factory