Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Abstract Factory pattern creates a coordinated family of related objects through interfaces, so Java client code can switch between families without naming their concrete classes. It fits when products such as a button and checkbox must come from the same platform or theme; for a single varying product, a simpler factory is often easier to maintain.

What is the Abstract Factory pattern?

Abstract Factory is a creational design pattern that provides an interface for creating families of related or dependent objects without exposing their concrete classes. The central idea is not merely to hide new; it is to make products that belong together available as a set. PMI Disciplined Agile describes its purpose as: “Create an interface for creating sets of dependant or related instances that implement a set of abstract types.” PMI Disciplined Agile

For example, a graphical application might need buttons and checkboxes that both follow the Windows look and feel, or both follow the Mac look and feel. The client works with the general product interfaces; a chosen factory supplies the matching implementations.

How the pattern is structured

  • Abstract factory: Declares a creation method for each product type in the family.
  • Concrete factory: Implements those methods for one family, such as Windows or Mac.
  • Abstract products: Interfaces or abstract classes that describe the operations available to client code.
  • Concrete products: Implementations of those product interfaces for a particular family.
  • Client: Receives a factory and uses its abstract products rather than constructing concrete products directly.

This arrangement keeps the family-selection decision at the boundary where the factory is chosen. The client can call the same product operations regardless of which family it receives. INRIA’s pattern description outlines the same roles: factory interface, concrete factories, abstract and concrete products, and a factory client.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Java example: matching buttons and checkboxes

The following compact example shows the core design. Each concrete factory returns products from one family, while the application depends only on the factory and product interfaces.

interface Button {
    void render();
}

interface Checkbox {
    void toggle();
}

interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

final class WindowsFactory implements GUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }

    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

final class MacFactory implements GUIFactory {
    public Button createButton() {
        return new MacButton();
    }

    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

final class Application {
    private final GUIFactory factory;

    Application(GUIFactory factory) {
        this.factory = factory;
    }

    void render() {
        Button button = factory.createButton();
        Checkbox checkbox = factory.createCheckbox();
        button.render();
        checkbox.toggle();
    }
}

WindowsButton, WindowsCheckbox, MacButton, and MacCheckbox are concrete implementations of their respective interfaces. They are omitted here to keep the focus on the factory relationships.

Application setup supplies the appropriate factory, for example new Application(new WindowsFactory()). In a real program, the platform or configuration decision belongs in this setup layer, not inside Application.render(). After construction, the application asks the factory for products without knowing their concrete classes. The Java look-and-feel example is also discussed in James W. Cooper’s Java Design Patterns: A Tutorial, Chapter 5.

Where Abstract Factory fits in Java applications

UI themes and platforms

Use a factory when several UI components need to vary together by platform or theme. If the factory supplies a button and a checkbox, the client need not independently choose each implementation and risk combining incompatible styles.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Storage-specific DAO sets

A data-access layer can expose a DAOFactory with methods such as getCustomerDAO(), getAccountDAO(), and getOrderDAO(). A concrete factory for a storage system supplies the corresponding DAO implementations, so the client obtains a coherent set from its selected factory. Oracle’s example describes factories for systems such as Cloudscape, Oracle, and Sybase. Oracle: Data Access Object

Provider adapters and test components

The same structure can help when a cloud provider has several related adapters, or when a test environment needs a matching set of substitute components. These are useful only if the products genuinely vary as a family; otherwise, a factory hierarchy can add ceremony without protecting a meaningful compatibility rule.

Abstract Factory vs. Factory Method

The patterns both hide concrete construction, but they address different variation needs. Abstract Factory organizes creation around a family of product types. Factory Method typically delegates creation of one product type to a subclass or method. O’Reilly characterizes Abstract Factory as a higher level of abstraction than Factory Method and describes it as a way to return groups of related classes. O’Reilly, Chapter 5

Comparison Abstract Factory Factory Method
Product types Creates a coordinated set, such as buttons and checkboxes. Usually focuses on one product type.
Variation Selects a product family or platform through a factory. Lets a subclass or method determine which product implementation to create.
Compatibility Designed to return products intended to work together. Does not, by itself, coordinate several product types.
Adding a family Usually means implementing another concrete factory and its products. Often means another creator implementation, depending on the design.
Adding a product type Usually requires a new method in the abstract factory and corresponding changes to each concrete factory. Depends on the design; the pattern is centered on the product-creation method rather than a family-wide set.
Client dependency Client uses abstract factory and product interfaces. Client uses the creator/product abstraction provided by the design.

Choose based on the axis that actually varies: one product implementation points toward Factory Method or a small factory; a coordinated collection points toward Abstract Factory.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Benefits, costs, and the main design trade-off

What it improves

  • Less coupling to concrete classes: Clients depend on stable product and factory interfaces rather than platform-specific implementations.
  • Family switching: Replacing the injected factory can change a complete family without rewriting the client’s product usage.
  • Fewer accidental mismatches: Factory methods centralize family selection, helping keep related products compatible.

What it costs

  • More types to maintain: The pattern introduces factory interfaces, concrete factories, product interfaces, and concrete products. Oracle cautions that both factory and product hierarchies must be designed.
  • New product types are expensive: Adding another kind of product generally changes the abstract-factory interface and every concrete factory. This is the pattern’s central trade-off: adding a new family is straightforward relative to adding a new product type across all families.
  • Possible over-abstraction: If there is no real family or compatibility constraint, the extra hierarchy can make a simple creation decision harder to follow.

These trade-offs are noted in Oracle’s DAO discussion; the family constraint also explains why the pattern is most useful when products need to vary together.

How to decide whether to use it

  • Use Abstract Factory if two or more related product types must change together across families.
  • Use it when a mixed set of products would be invalid, inconsistent, or difficult to detect in client code.
  • Prefer a simpler factory or Factory Method when only one product type varies.
  • Before adding the abstraction, identify the real families, their products, and the compatibility rule the factory will enforce.
  • Account for the cost of adding a new product type: every family-specific factory may need an update.

Further reading

For a longer treatment of the Java pattern, James W. Cooper’s Java Design Patterns: A Tutorial includes a dedicated Chapter 5 on Abstract Factory. View the chapter listing at O’Reilly.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.