Home/Learn/Low Level Design/Abstract Factory Pattern

Abstract Factory Pattern

Intermediate
Creational Patterns

Provides an interface for creating families of related objects without specifying their concrete classes.

Overview

Abstract Factory is a super-factory that creates other factories. It groups Factory Methods for related products under one interface. The classic example is a UI toolkit: an AbstractUIFactory declares createButton() and createCheckbox(); WindowsFactory returns Windows-styled widgets, MacFactory returns Mac-styled widgets. The client receives a factory (injected or chosen at startup) and creates a consistent family of products without knowing platform specifics. Abstract Factory enforces product family consistency — you cannot mix Windows buttons with Mac checkboxes.

Abstract Factory Implementation

Define abstract product interfaces for each product in the family. Define an AbstractFactory interface with one create method per product. Implement concrete factories per family. The client receives the factory via constructor injection.

Java — Abstract Factory (UI Toolkit example)
// Abstract Products
public interface Button {
    void render();
    void onClick();
}

public interface Checkbox {
    void render();
    boolean isChecked();
}

// Concrete Products — Windows family
public class WindowsButton implements Button {
    @Override public void render() { System.out.println("Rendering Windows Button"); }
    @Override public void onClick() { System.out.println("Windows Button clicked"); }
}

public class WindowsCheckbox implements Checkbox {
    private boolean checked = false;
    @Override public void render() { System.out.println("Rendering Windows Checkbox"); }
    @Override public boolean isChecked() { return checked; }
}

// Concrete Products — Mac family
public class MacButton implements Button {
    @Override public void render() { System.out.println("Rendering Mac Button"); }
    @Override public void onClick() { System.out.println("Mac Button clicked"); }
}

public class MacCheckbox implements Checkbox {
    private boolean checked = false;
    @Override public void render() { System.out.println("Rendering Mac Checkbox"); }
    @Override public boolean isChecked() { return checked; }
}

// Abstract Factory
public interface UIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// Concrete Factories
public class WindowsFactory implements UIFactory {
    @Override public Button createButton()     { return new WindowsButton(); }
    @Override public Checkbox createCheckbox() { return new WindowsCheckbox(); }
}

public class MacFactory implements UIFactory {
    @Override public Button createButton()     { return new MacButton(); }
    @Override public Checkbox createCheckbox() { return new MacCheckbox(); }
}

// Client — depends only on interfaces
public class Application {
    private final Button button;
    private final Checkbox checkbox;

    public Application(UIFactory factory) {
        this.button   = factory.createButton();
        this.checkbox = factory.createCheckbox();
    }

    public void render() {
        button.render();
        checkbox.render();
    }
}

// Wiring at startup
UIFactory factory = System.getProperty("os.name").startsWith("Mac")
    ? new MacFactory()
    : new WindowsFactory();
Application app = new Application(factory);
app.render();

Abstract Factory vs Factory Method

Factory Method uses inheritance to vary a single product; Abstract Factory uses composition to vary a family of products. Abstract Factory is essentially a set of Factory Methods grouped by family. Use Abstract Factory when the system must be independent of product creation and must work with multiple product families.

Java — Factory Method vs Abstract Factory contrast
// Factory Method — one product, subclass decides
abstract class Dialog {
    abstract Button createButton(); // single factory method
    void render() { createButton().render(); }
}

// Abstract Factory — multiple related products, injected factory
interface ThemeFactory {
    Button  createButton();
    TextBox createTextBox();
    Menu    createMenu();
    // All products share the same theme/family
}

// Key rule: Abstract Factory products must be used together.
// Mixing MacButton with WindowsTextBox is a logic error the compiler won't catch —
// design your factories to make this impossible.

Key Points to Remember

  • 1Abstract Factory creates a family of related objects; Factory Method creates one type of object.
  • 2Enforces product family consistency — prevents mixing objects from different families.
  • 3Adding a new product family requires a new concrete factory class (OCP-compliant).
  • 4Adding a new product type requires changing the AbstractFactory interface and ALL concrete factories (costly).
  • 5Commonly implemented with dependency injection — inject the factory, not the products directly.

Interview Questions

Sign in to ask Aria
1

What is the key difference between Abstract Factory and Factory Method?

MediumGoogle
2

How do you add a new product family without modifying existing code in Abstract Factory?

MediumAmazon
3

What is the downside of Abstract Factory when you need to add a new product type?

HardMicrosoft
4

Give a real-world Java example where Abstract Factory is used.

EasyAdobe

Ask Aria about Abstract Factory Pattern

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…