Abstract Factory Pattern
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Intent & Objective
Produce families of related objects (such as UI buttons, checkboxes, and windows) without depending on their concrete implementations, ensuring products from one family are never accidentally mixed with another.
"You can furnish a room in Modern, Victorian, or Industrial styles. The Modern factory creates a matching chair and table; the Victorian factory creates ornate mahogany sets, avoiding aesthetic clashes."
"Creating a family of Windows Fluent controls vs macOS Aqua controls, guaranteeing a window never pairs a Mac button with a Windows scrollbar."
The Problem
When creating suites of related components, client code might accidentally instantiate a Windows Button with a macOS Scrollbar, creating visual and behavioral inconsistencies.
The Solution
Define an Abstract Factory interface declaring creation methods for each product in the family (`createButton()`, `createCheckbox()`). Implement concrete factory classes for each family variant.
Key Participants & Architectural Roles
Code Samples (Traditional OOP vs Functional Programming)
Available in C++, Python, and JavaParadigm Contrast: Traditional OOP vs Functional / Data-Oriented
In OOP, Abstract Factory is a class containing multiple factory methods. In Functional Programming, an Abstract Factory is represented as a record/tuple of constructor functions or a module signature providing a cohesive set of builders.
Advantages
- β Guarantees compatibility between products of the same family
- β Isolates concrete product classes from client code
- β Follows Single Responsibility and Open/Closed principles
Trade-offs
- β Extending the factory to add new product types requires changing the Abstract Factory interface and all its subclasses
When to Apply
- β When your system must support multiple independent visual themes, cross-platform UI toolkits, or database drivers
- β When you need to enforce that product variants work together harmoniously
When to Avoid
- ! When you only have one single product type rather than families of related components