Abstract Factory Pattern - Creating Families of Related Objects
Learn the Abstract Factory pattern for creating families of related objects. TypeScript examples for theme systems, cross-platform UI, and database providers.
Detailed Explanation
Abstract Factory Pattern
The Abstract Factory pattern provides an interface for creating families of related objects without specifying their concrete classes. It ensures that products from one family are used together consistently.
Problem Scenario
Imagine a UI toolkit that supports dark and light themes. Each theme requires a matching set of buttons, inputs, and dialogs. Mixing a dark button with a light dialog creates visual inconsistency. Abstract Factory prevents this by encapsulating the creation of a complete family.
Structure
interface UIFactory {
createButton(): Button;
createDialog(): Dialog;
createInput(): Input;
}
class MaterialFactory implements UIFactory {
createButton() { return new MaterialButton(); }
createDialog() { return new MaterialDialog(); }
createInput() { return new MaterialInput(); }
}
class FluentFactory implements UIFactory {
createButton() { return new FluentButton(); }
createDialog() { return new FluentDialog(); }
createInput() { return new FluentInput(); }
}
Key Benefit
The client code works with factories and products through abstract interfaces. Switching from Material to Fluent design requires changing only one line: the factory instantiation. All downstream components automatically use the correct family.
Tradeoff
Adding a new product type (e.g., createCheckbox()) requires changing the factory interface and all concrete factories. This makes Abstract Factory rigid when the product set frequently changes. In such cases, consider the Builder pattern or configuration-based approaches.
Modern Usage
In modern TypeScript and React applications, Abstract Factory appears as theme providers, database driver factories (switching between PostgreSQL and MySQL), and cross-platform rendering engines.
Use Case
Abstract Factory is ideal for applications that must support multiple look-and-feel standards (Material, Fluent, Cupertino), cross-platform deployment targets (iOS, Android, Web), or swappable infrastructure providers (AWS, GCP, Azure) where all components must come from the same provider.