Skip to content

Abstract Factory Pattern

Category: Creational Pattern

Overview

Provide an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is useful when the system needs to be independent of how its objects are created and when families of related objects must be used together to ensure consistency.

Usage Guidelines

Use when:

  • System needs to work with multiple families of related products
  • Products from one family must be used together for consistency
  • You want to switch between product families easily
  • Application should be independent of product creation details

Avoid when:

  • Only one product family exists
  • Products aren't related or don't need to work together
  • Product creation is straightforward
  • Adding new product families requires modifying the factory interface

Implementation

from __future__ import annotations
from abc import ABC, abstractmethod

# Abstract Products
class Button(ABC):
    """Abstract interface for buttons."""

    @abstractmethod
    def render(self) -> str:
        """Render the button."""
        pass

    @abstractmethod
    def click(self) -> str:
        """Handle button click."""
        pass

class Checkbox(ABC):
    """Abstract interface for checkboxes."""

    @abstractmethod
    def render(self) -> str:
        """Render the checkbox."""
        pass

    @abstractmethod
    def toggle(self) -> str:
        """Toggle the checkbox state."""
        pass

# Concrete Products - Windows Family
class WindowsButton(Button):
    """Concrete Windows-style button."""

    def render(self) -> str:
        return "Rendering Windows button"

    def click(self) -> str:
        return "Windows button clicked"

class WindowsCheckbox(Checkbox):
    """Concrete Windows-style checkbox."""

    def render(self) -> str:
        return "Rendering Windows checkbox"

    def toggle(self) -> str:
        return "Windows checkbox toggled"

# Concrete Products - macOS Family
class MacOSButton(Button):
    """Concrete macOS-style button."""

    def render(self) -> str:
        return "Rendering macOS button"

    def click(self) -> str:
        return "macOS button clicked"

class MacOSCheckbox(Checkbox):
    """Concrete macOS-style checkbox."""

    def render(self) -> str:
        return "Rendering macOS checkbox"

    def toggle(self) -> str:
        return "macOS checkbox toggled"

# Abstract Factory
class GUIFactory(ABC):
    """Abstract factory for creating UI components."""

    @abstractmethod
    def create_button(self) -> Button:
        """Create a button."""
        pass

    @abstractmethod
    def create_checkbox(self) -> Checkbox:
        """Create a checkbox."""
        pass

# Concrete Factories
class WindowsFactory(GUIFactory):
    """Concrete factory for creating Windows UI components."""

    def create_button(self) -> Button:
        return WindowsButton()

    def create_checkbox(self) -> Checkbox:
        return WindowsCheckbox()

class MacOSFactory(GUIFactory):
    """Concrete factory for creating macOS UI components."""

    def create_button(self) -> Button:
        return MacOSButton()

    def create_checkbox(self) -> Checkbox:
        return MacOSCheckbox()

# Client
class Application:
    """Application that uses abstract factory to create UI components."""

    def __init__(self, factory: GUIFactory) -> None:
        """Initialize application with a GUI factory."""
        self.factory = factory
        self.button = factory.create_button()
        self.checkbox = factory.create_checkbox()

    def render(self) -> str:
        """Render the application UI."""
        return f"{self.button.render()}, {self.checkbox.render()}"

    def interact(self) -> str:
        """Interact with UI components."""
        return f"{self.button.click()}, {self.checkbox.toggle()}"

Usage

# Create Windows application
windows_factory = WindowsFactory()
app = Application(windows_factory)
print(app.render())  # Rendering Windows button, Rendering Windows checkbox
print(app.interact())  # Windows button clicked, Windows checkbox toggled

# Switch to macOS by changing factory
macos_factory = MacOSFactory()
app = Application(macos_factory)
print(app.render())  # Rendering macOS button, Rendering macOS checkbox
print(app.interact())  # macOS button clicked, macOS checkbox toggled

Trade-offs

Benefits:

  1. Isolates concrete classes from client code
  2. Ensures products from same family are used together
  3. Easy to switch between product families
  4. Easy to introduce new product families (Open/Closed Principle)

Drawbacks:

  1. Introduces many interfaces and classes, increasing complexity
  2. Adding new products requires changing all factories
  3. More abstract and harder to understand than simpler patterns
  4. Maintains parallel class hierarchies for products

Real-World Examples

  • Cross-platform UI frameworks creating platform-specific components
  • Database drivers for different databases
  • Document generators for PDF, HTML, Word formats
  • Theme systems with consistent styled components
  • Factory Method
  • Singleton
  • Prototype
  • Builder
  • Facade

API Reference

design_patterns.creational.abstract_factory

Abstract Factory Pattern Module

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is particularly useful when the system needs to be independent of how its objects are created and when families of related objects must be used together.

Example

Creating UI components for different platforms:

# Create a Windows UI factory
factory = WindowsFactory()
button = factory.create_button()
checkbox = factory.create_checkbox()

button.render()  # Renders Windows-style button
checkbox.render()  # Renders Windows-style checkbox

# Switch to macOS UI factory
factory = MacOSFactory()
button = factory.create_button()
checkbox = factory.create_checkbox()

button.render()  # Renders macOS-style button
checkbox.render()  # Renders macOS-style checkbox

Application

Application that uses abstract factory to create UI components.

Source code in src/design_patterns/creational/abstract_factory.py
class Application:
    """Application that uses abstract factory to create UI components."""

    def __init__(self, factory: GUIFactory) -> None:
        """Initialize application with a GUI factory.

        Args:
            factory: The GUI factory to use for creating components.
        """
        self.factory = factory
        self.button = factory.create_button()
        self.checkbox = factory.create_checkbox()

    def render(self) -> str:
        """Render the application UI.

        Returns:
            Combined rendering of all UI components.
        """
        return f"{self.button.render()}, {self.checkbox.render()}"

    def interact(self) -> str:
        """Interact with UI components.

        Returns:
            Combined interaction results.
        """
        return f"{self.button.click()}, {self.checkbox.toggle()}"

__init__(factory)

Initialize application with a GUI factory.

Parameters:

Name Type Description Default
factory GUIFactory

The GUI factory to use for creating components.

required
Source code in src/design_patterns/creational/abstract_factory.py
def __init__(self, factory: GUIFactory) -> None:
    """Initialize application with a GUI factory.

    Args:
        factory: The GUI factory to use for creating components.
    """
    self.factory = factory
    self.button = factory.create_button()
    self.checkbox = factory.create_checkbox()

interact()

Interact with UI components.

Returns:

Type Description
str

Combined interaction results.

Source code in src/design_patterns/creational/abstract_factory.py
def interact(self) -> str:
    """Interact with UI components.

    Returns:
        Combined interaction results.
    """
    return f"{self.button.click()}, {self.checkbox.toggle()}"

render()

Render the application UI.

Returns:

Type Description
str

Combined rendering of all UI components.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render the application UI.

    Returns:
        Combined rendering of all UI components.
    """
    return f"{self.button.render()}, {self.checkbox.render()}"

Button

Bases: ABC

Abstract interface for buttons.

Source code in src/design_patterns/creational/abstract_factory.py
class Button(ABC):
    """Abstract interface for buttons."""

    @abstractmethod
    def render(self) -> str:
        """Render the button.

        Returns:
            String representation of the rendered button.
        """
        pass

    @abstractmethod
    def click(self) -> str:
        """Handle button click.

        Returns:
            String describing the click action.
        """
        pass

click() abstractmethod

Handle button click.

Returns:

Type Description
str

String describing the click action.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def click(self) -> str:
    """Handle button click.

    Returns:
        String describing the click action.
    """
    pass

render() abstractmethod

Render the button.

Returns:

Type Description
str

String representation of the rendered button.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def render(self) -> str:
    """Render the button.

    Returns:
        String representation of the rendered button.
    """
    pass

Checkbox

Bases: ABC

Abstract interface for checkboxes.

Source code in src/design_patterns/creational/abstract_factory.py
class Checkbox(ABC):
    """Abstract interface for checkboxes."""

    @abstractmethod
    def render(self) -> str:
        """Render the checkbox.

        Returns:
            String representation of the rendered checkbox.
        """
        pass

    @abstractmethod
    def toggle(self) -> str:
        """Toggle the checkbox state.

        Returns:
            String describing the toggle action.
        """
        pass

render() abstractmethod

Render the checkbox.

Returns:

Type Description
str

String representation of the rendered checkbox.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def render(self) -> str:
    """Render the checkbox.

    Returns:
        String representation of the rendered checkbox.
    """
    pass

toggle() abstractmethod

Toggle the checkbox state.

Returns:

Type Description
str

String describing the toggle action.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def toggle(self) -> str:
    """Toggle the checkbox state.

    Returns:
        String describing the toggle action.
    """
    pass

GUIFactory

Bases: ABC

Abstract factory for creating UI components.

Source code in src/design_patterns/creational/abstract_factory.py
class GUIFactory(ABC):
    """Abstract factory for creating UI components."""

    @abstractmethod
    def create_button(self) -> Button:
        """Create a button.

        Returns:
            A button instance.
        """
        pass

    @abstractmethod
    def create_checkbox(self) -> Checkbox:
        """Create a checkbox.

        Returns:
            A checkbox instance.
        """
        pass

create_button() abstractmethod

Create a button.

Returns:

Type Description
Button

A button instance.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def create_button(self) -> Button:
    """Create a button.

    Returns:
        A button instance.
    """
    pass

create_checkbox() abstractmethod

Create a checkbox.

Returns:

Type Description
Checkbox

A checkbox instance.

Source code in src/design_patterns/creational/abstract_factory.py
@abstractmethod
def create_checkbox(self) -> Checkbox:
    """Create a checkbox.

    Returns:
        A checkbox instance.
    """
    pass

LinuxButton

Bases: Button

Concrete Linux-style button.

Source code in src/design_patterns/creational/abstract_factory.py
class LinuxButton(Button):
    """Concrete Linux-style button."""

    def render(self) -> str:
        """Render Linux button.

        Returns:
            Linux button rendering.
        """
        return "Rendering Linux button"

    def click(self) -> str:
        """Handle Linux button click.

        Returns:
            Linux click action.
        """
        return "Linux button clicked"

click()

Handle Linux button click.

Returns:

Type Description
str

Linux click action.

Source code in src/design_patterns/creational/abstract_factory.py
def click(self) -> str:
    """Handle Linux button click.

    Returns:
        Linux click action.
    """
    return "Linux button clicked"

render()

Render Linux button.

Returns:

Type Description
str

Linux button rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render Linux button.

    Returns:
        Linux button rendering.
    """
    return "Rendering Linux button"

LinuxCheckbox

Bases: Checkbox

Concrete Linux-style checkbox.

Source code in src/design_patterns/creational/abstract_factory.py
class LinuxCheckbox(Checkbox):
    """Concrete Linux-style checkbox."""

    def render(self) -> str:
        """Render Linux checkbox.

        Returns:
            Linux checkbox rendering.
        """
        return "Rendering Linux checkbox"

    def toggle(self) -> str:
        """Toggle Linux checkbox.

        Returns:
            Linux toggle action.
        """
        return "Linux checkbox toggled"

render()

Render Linux checkbox.

Returns:

Type Description
str

Linux checkbox rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render Linux checkbox.

    Returns:
        Linux checkbox rendering.
    """
    return "Rendering Linux checkbox"

toggle()

Toggle Linux checkbox.

Returns:

Type Description
str

Linux toggle action.

Source code in src/design_patterns/creational/abstract_factory.py
def toggle(self) -> str:
    """Toggle Linux checkbox.

    Returns:
        Linux toggle action.
    """
    return "Linux checkbox toggled"

LinuxFactory

Bases: GUIFactory

Concrete factory for creating Linux UI components.

Source code in src/design_patterns/creational/abstract_factory.py
class LinuxFactory(GUIFactory):
    """Concrete factory for creating Linux UI components."""

    def create_button(self) -> Button:
        """Create a Linux button.

        Returns:
            LinuxButton instance.
        """
        return LinuxButton()

    def create_checkbox(self) -> Checkbox:
        """Create a Linux checkbox.

        Returns:
            LinuxCheckbox instance.
        """
        return LinuxCheckbox()

create_button()

Create a Linux button.

Returns:

Type Description
Button

LinuxButton instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_button(self) -> Button:
    """Create a Linux button.

    Returns:
        LinuxButton instance.
    """
    return LinuxButton()

create_checkbox()

Create a Linux checkbox.

Returns:

Type Description
Checkbox

LinuxCheckbox instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_checkbox(self) -> Checkbox:
    """Create a Linux checkbox.

    Returns:
        LinuxCheckbox instance.
    """
    return LinuxCheckbox()

MacOSButton

Bases: Button

Concrete macOS-style button.

Source code in src/design_patterns/creational/abstract_factory.py
class MacOSButton(Button):
    """Concrete macOS-style button."""

    def render(self) -> str:
        """Render macOS button.

        Returns:
            macOS button rendering.
        """
        return "Rendering macOS button"

    def click(self) -> str:
        """Handle macOS button click.

        Returns:
            macOS click action.
        """
        return "macOS button clicked"

click()

Handle macOS button click.

Returns:

Type Description
str

macOS click action.

Source code in src/design_patterns/creational/abstract_factory.py
def click(self) -> str:
    """Handle macOS button click.

    Returns:
        macOS click action.
    """
    return "macOS button clicked"

render()

Render macOS button.

Returns:

Type Description
str

macOS button rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render macOS button.

    Returns:
        macOS button rendering.
    """
    return "Rendering macOS button"

MacOSCheckbox

Bases: Checkbox

Concrete macOS-style checkbox.

Source code in src/design_patterns/creational/abstract_factory.py
class MacOSCheckbox(Checkbox):
    """Concrete macOS-style checkbox."""

    def render(self) -> str:
        """Render macOS checkbox.

        Returns:
            macOS checkbox rendering.
        """
        return "Rendering macOS checkbox"

    def toggle(self) -> str:
        """Toggle macOS checkbox.

        Returns:
            macOS toggle action.
        """
        return "macOS checkbox toggled"

render()

Render macOS checkbox.

Returns:

Type Description
str

macOS checkbox rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render macOS checkbox.

    Returns:
        macOS checkbox rendering.
    """
    return "Rendering macOS checkbox"

toggle()

Toggle macOS checkbox.

Returns:

Type Description
str

macOS toggle action.

Source code in src/design_patterns/creational/abstract_factory.py
def toggle(self) -> str:
    """Toggle macOS checkbox.

    Returns:
        macOS toggle action.
    """
    return "macOS checkbox toggled"

MacOSFactory

Bases: GUIFactory

Concrete factory for creating macOS UI components.

Source code in src/design_patterns/creational/abstract_factory.py
class MacOSFactory(GUIFactory):
    """Concrete factory for creating macOS UI components."""

    def create_button(self) -> Button:
        """Create a macOS button.

        Returns:
            MacOSButton instance.
        """
        return MacOSButton()

    def create_checkbox(self) -> Checkbox:
        """Create a macOS checkbox.

        Returns:
            MacOSCheckbox instance.
        """
        return MacOSCheckbox()

create_button()

Create a macOS button.

Returns:

Type Description
Button

MacOSButton instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_button(self) -> Button:
    """Create a macOS button.

    Returns:
        MacOSButton instance.
    """
    return MacOSButton()

create_checkbox()

Create a macOS checkbox.

Returns:

Type Description
Checkbox

MacOSCheckbox instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_checkbox(self) -> Checkbox:
    """Create a macOS checkbox.

    Returns:
        MacOSCheckbox instance.
    """
    return MacOSCheckbox()

WindowsButton

Bases: Button

Concrete Windows-style button.

Source code in src/design_patterns/creational/abstract_factory.py
class WindowsButton(Button):
    """Concrete Windows-style button."""

    def render(self) -> str:
        """Render Windows button.

        Returns:
            Windows button rendering.
        """
        return "Rendering Windows button"

    def click(self) -> str:
        """Handle Windows button click.

        Returns:
            Windows click action.
        """
        return "Windows button clicked"

click()

Handle Windows button click.

Returns:

Type Description
str

Windows click action.

Source code in src/design_patterns/creational/abstract_factory.py
def click(self) -> str:
    """Handle Windows button click.

    Returns:
        Windows click action.
    """
    return "Windows button clicked"

render()

Render Windows button.

Returns:

Type Description
str

Windows button rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render Windows button.

    Returns:
        Windows button rendering.
    """
    return "Rendering Windows button"

WindowsCheckbox

Bases: Checkbox

Concrete Windows-style checkbox.

Source code in src/design_patterns/creational/abstract_factory.py
class WindowsCheckbox(Checkbox):
    """Concrete Windows-style checkbox."""

    def render(self) -> str:
        """Render Windows checkbox.

        Returns:
            Windows checkbox rendering.
        """
        return "Rendering Windows checkbox"

    def toggle(self) -> str:
        """Toggle Windows checkbox.

        Returns:
            Windows toggle action.
        """
        return "Windows checkbox toggled"

render()

Render Windows checkbox.

Returns:

Type Description
str

Windows checkbox rendering.

Source code in src/design_patterns/creational/abstract_factory.py
def render(self) -> str:
    """Render Windows checkbox.

    Returns:
        Windows checkbox rendering.
    """
    return "Rendering Windows checkbox"

toggle()

Toggle Windows checkbox.

Returns:

Type Description
str

Windows toggle action.

Source code in src/design_patterns/creational/abstract_factory.py
def toggle(self) -> str:
    """Toggle Windows checkbox.

    Returns:
        Windows toggle action.
    """
    return "Windows checkbox toggled"

WindowsFactory

Bases: GUIFactory

Concrete factory for creating Windows UI components.

Source code in src/design_patterns/creational/abstract_factory.py
class WindowsFactory(GUIFactory):
    """Concrete factory for creating Windows UI components."""

    def create_button(self) -> Button:
        """Create a Windows button.

        Returns:
            WindowsButton instance.
        """
        return WindowsButton()

    def create_checkbox(self) -> Checkbox:
        """Create a Windows checkbox.

        Returns:
            WindowsCheckbox instance.
        """
        return WindowsCheckbox()

create_button()

Create a Windows button.

Returns:

Type Description
Button

WindowsButton instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_button(self) -> Button:
    """Create a Windows button.

    Returns:
        WindowsButton instance.
    """
    return WindowsButton()

create_checkbox()

Create a Windows checkbox.

Returns:

Type Description
Checkbox

WindowsCheckbox instance.

Source code in src/design_patterns/creational/abstract_factory.py
def create_checkbox(self) -> Checkbox:
    """Create a Windows checkbox.

    Returns:
        WindowsCheckbox instance.
    """
    return WindowsCheckbox()