The Abstract Factory pattern provides an interface for creating families of related objects without specifying their concrete classes. While the Factory Method creates one product, the Abstract Factory creates an entire suite of products that are designed to work together. This is the pattern you reach for when your system needs to support multiple variants of a product family.
Imagine building a cross-platform UI toolkit that must render components differently on Windows, macOS, and Linux. Each platform needs its own buttons, text inputs, checkboxes, and dialogs — but they must be internally consistent. A Windows button should never accidentally appear alongside a macOS checkbox. If you create each component independently, you risk mixing platform-specific implementations in ways that break the user experience.
The Abstract Factory defines an interface with creation methods for each component type (button, text input, checkbox). Each platform provides a concrete factory that produces the matching component family. The application code works exclusively through the abstract interfaces — it never knows which platform-specific classes it is using. Switching platforms means swapping one factory for another.
Ensure product compatibility by constraining creation to families. The abstract factory guarantees that all objects produced by a single factory are designed to work together, eliminating cross-family mixing at the structural level.
This example creates a UI component factory system that produces consistent component families for different themes (Material and iOS).
// Abstract products
public interface Button {
String render();
String onClick(String action);
}
public interface TextField {
String render(String placeholder);
String getValue();
}
public interface Checkbox {
String render(String label);
boolean isChecked();
}
// Material Design implementations
public class MaterialButton implements Button {
@Override
public String render() {
return "[Material Button with ripple effect and elevation]";
}
@Override
public String onClick(String action) {
return "Material ripple animation -> " + action;
}
}
public class MaterialTextField implements TextField {
private String value = "";
@Override
public String render(String placeholder) {
return "[Material TextField: floating label '" + placeholder + "']";
}
@Override
public String getValue() { return value; }
}
public class MaterialCheckbox implements Checkbox {
private boolean checked = false;
@Override
public String render(String label) {
return "[Material Checkbox: " + label + " with animated checkmark]";
}
@Override
public boolean isChecked() { return checked; }
}
// iOS implementations
public class IOSButton implements Button {
@Override
public String render() {
return "[iOS Button with haptic feedback and rounded corners]";
}
@Override
public String onClick(String action) {
return "iOS haptic tap -> " + action;
}
}
public class IOSTextField implements TextField {
private String value = "";
@Override
public String render(String placeholder) {
return "[iOS TextField: inline placeholder '" + placeholder + "']";
}
@Override
public String getValue() { return value; }
}
public class IOSCheckbox implements Checkbox {
private boolean checked = false;
@Override
public String render(String label) {
return "[iOS Toggle Switch: " + label + " with smooth slide]";
}
@Override
public boolean isChecked() { return checked; }
}
// Abstract factory interface
public interface UIComponentFactory {
Button createButton();
TextField createTextField();
Checkbox createCheckbox();
}
// Concrete factories
public class MaterialUIFactory implements UIComponentFactory {
@Override
public Button createButton() { return new MaterialButton(); }
@Override
public TextField createTextField() { return new MaterialTextField(); }
@Override
public Checkbox createCheckbox() { return new MaterialCheckbox(); }
}
public class IOSUIFactory implements UIComponentFactory {
@Override
public Button createButton() { return new IOSButton(); }
@Override
public TextField createTextField() { return new IOSTextField(); }
@Override
public Checkbox createCheckbox() { return new IOSCheckbox(); }
}
// Client code works with abstractions only
public class LoginForm {
private final Button submitButton;
private final TextField usernameField;
private final TextField passwordField;
private final Checkbox rememberMe;
public LoginForm(UIComponentFactory factory) {
this.submitButton = factory.createButton();
this.usernameField = factory.createTextField();
this.passwordField = factory.createTextField();
this.rememberMe = factory.createCheckbox();
}
public void render() {
System.out.println("=== Login Form ===");
System.out.println(usernameField.render("Username"));
System.out.println(passwordField.render("Password"));
System.out.println(rememberMe.render("Remember me"));
System.out.println(submitButton.render());
System.out.println(submitButton.onClick("submit login"));
}
public static void main(String[] args) {
// Switch theme by swapping the factory
String theme = "material";
UIComponentFactory factory = theme.equals("ios")
? new IOSUIFactory()
: new MaterialUIFactory();
LoginForm form = new LoginForm(factory);
form.render();
}
}
The same UI component factory system in Python, using abstract base classes.
from abc import ABC, abstractmethod
# Abstract products
class Button(ABC):
@abstractmethod
def render(self) -> str:
pass
@abstractmethod
def on_click(self, action: str) -> str:
pass
class TextField(ABC):
@abstractmethod
def render(self, placeholder: str) -> str:
pass
@abstractmethod
def get_value(self) -> str:
pass
class Checkbox(ABC):
@abstractmethod
def render(self, label: str) -> str:
pass
@abstractmethod
def is_checked(self) -> bool:
pass
# Material Design implementations
class MaterialButton(Button):
def render(self) -> str:
return "[Material Button with ripple effect and elevation]"
def on_click(self, action: str) -> str:
return f"Material ripple animation -> {action}"
class MaterialTextField(TextField):
def __init__(self):
self._value = ""
def render(self, placeholder: str) -> str:
return f"[Material TextField: floating label '{placeholder}']"
def get_value(self) -> str:
return self._value
class MaterialCheckbox(Checkbox):
def __init__(self):
self._checked = False
def render(self, label: str) -> str:
return f"[Material Checkbox: {label} with animated checkmark]"
def is_checked(self) -> bool:
return self._checked
# iOS implementations
class IOSButton(Button):
def render(self) -> str:
return "[iOS Button with haptic feedback and rounded corners]"
def on_click(self, action: str) -> str:
return f"iOS haptic tap -> {action}"
class IOSTextField(TextField):
def __init__(self):
self._value = ""
def render(self, placeholder: str) -> str:
return f"[iOS TextField: inline placeholder '{placeholder}']"
def get_value(self) -> str:
return self._value
class IOSCheckbox(Checkbox):
def __init__(self):
self._checked = False
def render(self, label: str) -> str:
return f"[iOS Toggle Switch: {label} with smooth slide]"
def is_checked(self) -> bool:
return self._checked
# Abstract factory
class UIComponentFactory(ABC):
@abstractmethod
def create_button(self) -> Button:
pass
@abstractmethod
def create_text_field(self) -> TextField:
pass
@abstractmethod
def create_checkbox(self) -> Checkbox:
pass
# Concrete factories
class MaterialUIFactory(UIComponentFactory):
def create_button(self) -> Button:
return MaterialButton()
def create_text_field(self) -> TextField:
return MaterialTextField()
def create_checkbox(self) -> Checkbox:
return MaterialCheckbox()
class IOSUIFactory(UIComponentFactory):
def create_button(self) -> Button:
return IOSButton()
def create_text_field(self) -> TextField:
return IOSTextField()
def create_checkbox(self) -> Checkbox:
return IOSCheckbox()
# Client code works with abstractions only
class LoginForm:
def __init__(self, factory: UIComponentFactory):
self.submit_button = factory.create_button()
self.username_field = factory.create_text_field()
self.password_field = factory.create_text_field()
self.remember_me = factory.create_checkbox()
def render(self):
print("=== Login Form ===")
print(self.username_field.render("Username"))
print(self.password_field.render("Password"))
print(self.remember_me.render("Remember me"))
print(self.submit_button.render())
print(self.submit_button.on_click("submit login"))
# Usage
if __name__ == "__main__":
theme = "material"
factory = IOSUIFactory() if theme == "ios" else MaterialUIFactory()
form = LoginForm(factory)
form.render()
LookAndFeel system uses abstract factories to produce platform-consistent UI components (buttons, scrollbars, menus).DocumentBuilderFactory and SAXParserFactory produce families of XML parsing components.