Skip to main content

Abstract Factory

Abstract Factory creates families of related objects through a single interface, guaranteeing the products are compatible. It makes swapping whole families easy but resists adding new product kinds.

Type
Creational
When to Use
Families Of Related Objects, Enforce Product Consistency, Swap Entire Product Set, Hide Concrete Classes

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without naming their concrete classes. It solves the problem of keeping a set of products mutually consistent — for example, ensuring that all widgets in an application share a single look-and-feel, or that all data-access objects target the same database engine.

How It Works

An Abstract Factory interface declares one creation method per product kind. Each Concrete Factory implements those methods to produce a coherent family of Concrete Products, each of which conforms to an Abstract Product interface. Client code holds a reference to the abstract factory and the abstract products; it never sees concrete types. At startup, the application picks one concrete factory and passes it everywhere, so every object created belongs to the same family.

Because the factory is selected once, swapping the entire product set is a single substitution. The factory itself is frequently a Singleton, since one instance usually suffices.

When to Use It

Use Abstract Factory when your system must be independent of how its products are created and composed, when it must work with multiple families of products, and when you want to enforce that products from the same family are used together. Typical cases include cross-platform UI kits, pluggable persistence layers, and themeable component libraries.

Avoid it when there is only one product family or when product kinds change often — adding a new product type forces a change to the abstract factory interface and every concrete factory, which is expensive.

Trade-offs

The pattern isolates concrete classes and guarantees family consistency, which is its standout benefit. It also makes exchanging families trivial and promotes the single-responsibility principle by concentrating construction code.

The principal drawback is rigidity along the product-kind axis. The interface fixes the set of products it can create; introducing a new kind ripples across all factories. The pattern also adds several layers of abstraction that can feel heavy for small applications. Teams sometimes combine it with Factory Method, implementing each creation method as a factory method, which trades flexibility for more classes.

Related Patterns

Abstract Factory is often built from Factory Methods. It pairs with Singleton because a single factory instance is common. Builder is a complementary creational pattern, but it focuses on assembling one complex object step by step rather than producing families. Prototype can implement a factory by cloning prototypical instances instead of subclassing.

Example

A reporting tool supports PDF and HTML output. An abstract DocumentFactory declares createHeader(), createChart(), and createTable(). PdfFactory returns PDF-rendering versions; HtmlFactory returns HTML versions. The report generator receives a factory and assembles a document; switching output formats means injecting a different factory, with zero changes to the generator. This guarantees a report never mixes a PDF chart with an HTML table.