← Back

Abstract Factory Design Pattern in Python: Creating Families of Related Objects

Posted on Sun 24 May 2026 in Python

Imagine you are developing a desktop application that supports both Windows and macOS.

Your application needs:

Windows:
    Button
    Checkbox
    TextBox

macOS:
    Button
    Checkbox
    TextBox

The problem is not simply creating one object. The application needs to create a family of related objects that belong to the same environment.

A Windows button should work naturally with Windows checkboxes. A macOS button should work with macOS checkboxes.

This is where the Abstract Factory Design Pattern becomes useful.

Refactoring.Guru defines Abstract Factory as a creational pattern that allows applications to produce families of related objects without specifying their concrete classes.

What Is Abstract Factory?

The Abstract Factory pattern provides an interface for creating multiple related products.

Instead of having:

Create Windows Button
Create Windows Checkbox
Create Windows TextBox

directly throughout the application, we define a factory:

GUI Factory
   |
   +---- create_button()
   |
   +---- create_checkbox()
   |
   +---- create_textbox()

Then provide concrete factories:

WindowsFactory
   |
   +---- WindowsButton
   +---- WindowsCheckbox
   +---- WindowsTextBox

MacFactory
   |
   +---- MacButton
   +---- MacCheckbox
   +---- MacTextBox

The client works with the abstract factory and does not need to know which concrete family is being created.

Python Example

First, define abstract products:

from abc import ABC, abstractmethod

class Button(ABC):

    @abstractmethod
    def render(self):
        pass

class Checkbox(ABC):

    @abstractmethod
    def render(self):
        pass

Now create Windows products:

class WindowsButton(Button):

    def render(self):
        print("Rendering Windows button")

class WindowsCheckbox(Checkbox):

    def render(self):
        print("Rendering Windows checkbox")

And macOS products:

class MacButton(Button):

    def render(self):
        print("Rendering macOS button")

class MacCheckbox(Checkbox):

    def render(self):
        print("Rendering macOS checkbox")

Next, define the abstract factory:

class GUIFactory(ABC):

    @abstractmethod
    def create_button(self):
        pass

    @abstractmethod
    def create_checkbox(self):
        pass

Create the Windows factory:

class WindowsFactory(GUIFactory):

    def create_button(self):
        return WindowsButton()

    def create_checkbox(self):
        return WindowsCheckbox()

Create the macOS factory:

class MacFactory(GUIFactory):

    def create_button(self):
        return MacButton()

    def create_checkbox(self):
        return MacCheckbox()

Now the application can work with either family:

factory = WindowsFactory()

button = factory.create_button()
checkbox = factory.create_checkbox()

button.render()
checkbox.render()

The client does not directly instantiate WindowsButton() or WindowsCheckbox(). Instead, it works through the factory.

Why Is It Called a "Family"?

This is the most important concept to understand.

Suppose you have a furniture application. Each furniture style contains:

Modern:
    Modern Chair
    Modern Sofa
    Modern Table

Victorian:
    Victorian Chair
    Victorian Sofa
    Victorian Table

These are families of related products.

Refactoring.Guru uses a similar furniture example and explains that each concrete factory corresponds to a particular product variant.

The factory guarantees that the products belong to the same family.

ModernFactory
     |
     +--> ModernChair
     +--> ModernSofa
     +--> ModernTable

This is different from simply creating different types of objects independently.

Dark Mode and Light Mode

Another practical example is a UI system supporting themes.

Light Theme
    LightButton
    LightCheckbox
    LightMenu

Dark Theme
    DarkButton
    DarkCheckbox
    DarkMenu

Instead of scattering theme-specific object creation throughout the application, we can select one factory:

factory = DarkThemeFactory()

Then:

button = factory.create_button()
checkbox = factory.create_checkbox()
menu = factory.create_menu()

The entire UI receives a consistent family of components.

Abstract Factory vs Factory Method

These two patterns are related but solve different problems.

Factory Method usually focuses on creating one type of product.

Transport Factory
      |
      +---- Truck
      +---- Ship
      +---- Airplane

Abstract Factory creates multiple related products.

Windows Factory
      |
      +---- Button
      +---- Checkbox
      +---- Menu

A useful way to remember this: Factory Method creates a product; Abstract Factory creates a family of related products.

Advantages

Consistent Product Families — The factory ensures that related products belong to the same variant.

Reduced Coupling — Client code depends on abstract interfaces rather than concrete classes.

Easy Environment Switching — The application can switch from Windows to macOS, or from light theme to dark theme, by changing the factory.

Better Scalability — New product families can be introduced through additional concrete factories.

Disadvantages

Abstract Factory can introduce many classes and interfaces. If your application only needs one or two simple objects, this pattern may be unnecessarily complex.

Adding a new product type to every family can also require changes to the abstract factory and all concrete factories.

When Should You Use Abstract Factory?

Consider it when:

  • You need multiple related products
  • Products must remain compatible with each other
  • The application supports multiple environments or platforms
  • You want to switch entire product families
  • You want client code to remain independent of concrete classes

Conclusion

The Abstract Factory pattern is about creating consistent families of related objects.

The core idea is: choose one factory, and let that factory create all products belonging to the same family.

It is especially useful for cross-platform UI systems, themes, database providers, cloud providers, and applications that support multiple product variants.