Skip to content

Abstract Factory Pattern — Families of Related Objects

DodaTech Updated 2026-06-24 4 min read

In this tutorial, you'll learn about Abstract Factory Pattern. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

What You'll Learn

You will discover how the Abstract Factory pattern lets you compose systems from interchangeable product families, ensuring that objects from the same family work together seamlessly. You will see how it builds on the Factory Method pattern.

Why It Matters

Modern applications often need to support multiple themes, platforms, or data sources. Hardcoding these variants leads to sprawling conditional logic. Abstract Factory centralises the variant selection, so swapping an entire product family becomes a single configuration change. For example, switching your UI from a Windows look-and-feel to a macOS look-and-feel should not require editing every dialog — it should require changing one Factory choice at startup.

Real-World Use

Cross-platform UI toolkits (e.g., Qt, Java Swing) use Abstract Factory to produce buttons, text fields, and menus that match the operating system's look and feel. DodaTech's reporting engine uses an Abstract Factory to generate PDF, HTML, or Markdown reports from the same data model — selecting the Factory determines whether the output is a binary PDF, a styled HTML page, or plain Markdown, without the data model knowing about any of them.

The Pattern

The client uses an Abstract Factory interface. Concrete factories implement it to produce concrete products that belong together.

from abc import ABC, abstractmethod

class Button(ABC):
    @abstractmethod
    def paint(self) -> str:
        pass

class Checkbox(ABC):
    @abstractmethod
    def paint(self) -> str:
        pass

class WinButton(Button):
    def paint(self) -> str:
        return "Windows-style button"

class WinCheckbox(Checkbox):
    def paint(self) -> str:
        return "Windows-style checkbox"

class MacButton(Button):
    def paint(self) -> str:
        return "macOS-style button"

class MacCheckbox(Checkbox):
    def paint(self) -> str:
        return "macOS-style checkbox"

class GUIFactory(ABC):
    @abstractmethod
    def create_button(self) -> Button:
        pass

    @abstractmethod
    def create_checkbox(self) -> Checkbox:
        pass

class WinFactory(GUIFactory):
    def create_button(self) -> Button:
        return WinButton()

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

class MacFactory(GUIFactory):
    def create_button(self) -> Button:
        return MacButton()

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

def render_ui(factory: GUIFactory):
    btn = factory.create_button()
    chk = factory.create_checkbox()
    print(btn.paint(), chk.paint())
render_ui(WinFactory())
render_ui(MacFactory())
Windows-style button Windows-style checkbox
macOS-style button macOS-style checkbox

Structure

classDiagram
    class AbstractFactory {
        +createProductA(): AbstractProductA
        +createProductB(): AbstractProductB
    }
    class ConcreteFactory1 {
        +createProductA(): ProductA1
        +createProductB(): ProductB1
    }
    class ConcreteFactory2 {
        +createProductA(): ProductA2
        +createProductB(): ProductB2
    }
    class AbstractProductA
    class AbstractProductB
    class ProductA1
    class ProductA2
    class ProductB1
    class ProductB2
    ConcreteFactory1 --|> AbstractFactory
    ConcreteFactory2 --|> AbstractFactory
    ProductA1 ..|> AbstractProductA
    ProductA2 ..|> AbstractProductA
    ProductB1 ..|> AbstractProductB
    ProductB2 ..|> AbstractProductB
    ConcreteFactory1 --> ProductA1 : creates
    ConcreteFactory1 --> ProductB1 : creates
    ConcreteFactory2 --> ProductA2 : creates
    ConcreteFactory2 --> ProductB2 : creates

Real-World Usage

  • Java javax.xml.parsers.DocumentBuilderFactory — creates SAX and DOM parsers through an Abstract Factory.
  • Python's SQLAlchemy dialects — each database backend has a Factory producing the correct SQL compiler, type compiler, and statement execution engine.
  • AWS SDK credential providersAbstract Factory pattern supplies credentials from environment variables, IAM roles, or profile files.
  • Factory Method is often used within Abstract Factory to create individual products.
  • Singleton often holds the concrete factory instance.
  • Builder separates complex construction from representation, complementing Abstract Factory.

Pros and Cons

Pros Cons
Ensures product consistency within a family Adding new products requires changing the Factory interface
Isolates concrete classes from clients Can introduce unnecessary complexity for simple hierarchies
Swapping product families is trivial Overhead of creating and maintaining Factory classes
Follows the Open/Closed Principle at the family level May not suit systems with few product types

The render_ui function accepts any GUIFactory and uses it to create both a button and a checkbox. The critical guarantee is that a WinFactory always creates matching Windows-style components, and a MacFactory always creates matching macOS-style components. This consistency across product families is the pattern's primary value.

Practice Questions

  1. How would you add a new product type (e.g., Slider) to an existing Abstract Factory without breaking existing concrete factories?
  2. Compare Abstract Factory with passing Factory Method references around — when does one become preferable over the other?
  3. Implement a Factory registry that selects the correct concrete Factory based on a runtime configuration string.
  4. How does the Abstract Factory pattern interact with the Dependency Inversion Principle?

Challenge

Add a third product family — Linux GTK-style components — by creating LinuxButton, LinuxCheckbox, and LinuxFactory. Verify that render_ui works unchanged with your new Factory.

Real-World Task

Identify a part of your application that creates related groups of objects (e.g., different data access handlers for different storage backends). Refactor it to use Abstract Factory and use DodaTech's architecture diff tool to compare the before and after dependency graphs.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro