0/0
Design Patterns

Abstract Factory Pattern

Produce FAMILIES of related products through one swappable factory β€” change the factory and the entire family changes together.

Explore Topics

🎯
Intent
One factory interface, many compatible product families β€” pick the family at runtime.
🏭 Family Matrix Switcher β€” one factory, one complete family
// CLIENT CODE β€” abstract types only, does NOT change when you swap the factory
FurnitureFactory factory = new ModernFactory();
Chair chair = factory.createChair();
Sofa sofa = factory.createSofa();
CoffeeTable table = factory.createCoffeeTable();
Family Matrix Β· variants Γ— product types
πŸͺ‘Chair
πŸ›‹οΈSofa
β˜•CoffeeTable
ModernChairminimal steel + beige fabric
ModernSofa3-seat low profile, oak legs
ModernCoffeeTableround glass top, chrome base
VictorianChaircarved mahogany, velvet uphol.
VictorianSofatufted, button-back, claw feet
VictorianCoffeeTableornate walnut, marble inlay
ArtDecoChairgeometric brass, lacquered seat
ArtDecoSofabold curves, gold accents, velvet
ArtDecoCoffeeTablestepped marble, gilded edges
Pick a row β†’ the entire row lights up. ALL three products come from the SAME family.
Mixing rows is impossible β€” that's the family-cohesion guarantee.
🏠 Showroom Preview · Modern family
minimal forms, steel, glass, oak β€” Bauhaus-inflected
πŸͺ‘ModernChairminimal steel + beige fabric
πŸ›‹οΈModernSofa3-seat low profile, oak legs
β˜•ModernCoffeeTableround glass top, chrome base
βœ“ All three products share the modern family
Hide 2 product columns β†’ you have Factory Method. Add more product columns β†’ richer family.
🎯
Intent
One factory interface, many compatible product families β€” pick the family at runtime.

Abstract Factory is a creational pattern that provides an interface for creating FAMILIES of related products without specifying their concrete classes. Where Factory Method has ONE polymorphic factory method per Creator subclass (one product type), Abstract Factory bundles MULTIPLE factory methods on a single AbstractFactory interface β€” one per product type in the family. The client picks a ConcreteFactory once at startup; from then on every product the client receives is guaranteed to come from the same family. This is why Abstract Factory is often called the "factory of factories": each concrete factory groups several individual factory methods into a single coordinated bundle, and switching factories swaps the whole bundle atomically.

Key Ideas
  • A FAMILY of related products is created together, not one product at a time.
  • The client depends only on the AbstractFactory interface and abstract Product interfaces.
  • Switching ConcreteFactory swaps the ENTIRE family β€” never a mix of variants.
  • Each create*() method on the AbstractFactory is conceptually a Factory Method β€” Abstract Factory composes several of them.
  • "Factory of factories" β€” one ConcreteFactory packages several Factory Method overrides into one coordinated bundle.
Strengths
  • ✦Guarantees compatible products are used together (no family mismatches)
  • ✦Isolates concrete classes β€” client never names a ConcreteProduct
  • ✦Swapping families = swapping ONE factory reference at startup
  • ✦Each ConcreteFactory has a single responsibility: produce ONE complete family
Weaknesses
  • β–³Requires inheritance AND composition β€” heavier than Factory Method
  • β–³Class explosion: N variants Γ— M product types + 2N abstract types
  • β–³Adding a NEW product type to the family requires editing the AbstractFactory interface AND every ConcreteFactory
  • β–³Overkill when the product family is fixed or small
Used in:The JDK uses Abstract Factory in `javax.xml.parsers.DocumentBuilderFactory`: pick a concrete factory once (`newInstance()` reads system properties to choose Xerces, Crimson, or another XML implementation), and from then on every `DocumentBuilder` and `Document` produced comes from that one implementation family. Switching the system property at startup re-themes the entire XML parsing stack without changing application code.
Code Snippets

Quiz

Intent Quiz
QUIZ 1/6
Which statement best captures the GoF Intent of the Abstract Factory pattern?

Diagrams

UML Class Diagram β€” the GoF Abstract Factory structure
Loading diagram...
Family Matrix β€” variants Γ— product types, with each ConcreteFactory producing one row
Loading diagram...

Practice

Drag each class from the FurnitureShopApp into the GoF Abstract Factory participant role it plays. Each role accepts exactly two classes.
EXERCISE 1/4
Chair (interface with describe method)
Sofa (interface with describe method)
ModernChair (implements Chair.describe)
VictorianSofa (implements Sofa.describe)
FurnitureFactory (interface with createChair, createSofa, createCoffeeTable)
MotorhomeFactory (interface with createFrame, createStyle, createEngine, createKitchen)
ModernFactory (implements FurnitureFactory)
TypeBFactory (implements MotorhomeFactory)
Showroom (uses an injected FurnitureFactory)
Manufacturer (uses an injected MotorhomeFactory)
Abstract Product
Concrete Product
Abstract Factory
Concrete Factory
Client
Spot the bug β€” why does this client defeat the Abstract Factory pattern?
EXERCISE 2/4
Click on the line you think contains the bug, then press Confirm.
1class Showroom {
2 void furnishLivingRoom(FurnitureFactory factory) {
3 Chair chair = factory.createChair();
4 Sofa sofa = new VictorianSofa(); // <- look here
5 CoffeeTable table = factory.createCoffeeTable();
6
7 System.out.println(chair.describe());
8 System.out.println(sofa.describe());
9 System.out.println(table.describe());
10 }
11}
12
13// caller:
14new Showroom().furnishLivingRoom(new ModernFactory());
15// Prints: Modern Chair, Victorian Sofa, Modern CoffeeTable
16// -- FAMILY MISMATCH, but compiler said nothing.
Order the 6 GoF implementation steps for refactoring scattered `new` to Abstract Factory
EXERCISE 3/4
Drag the lines into the correct order.
1. Draw the product MATRIX (M product types Γ— N variants) to see the shape and class count.
2. Declare M abstract product interfaces, one per product type in the family.
3. Make every existing concrete product class implement its abstract product interface.
4. Declare the AbstractFactory interface with N create*() methods, one per product type.
5. Implement one ConcreteFactory per variant; every create*() returns a product of that variant.
6. Replace direct `new ConcreteProduct()` calls in client code with `factory.createX()` calls; inject the factory at startup.
Abstract Factory myths and gotchas β€” true or false?
EXERCISE 4/4
Abstract Factory is the same as Factory Method.
Abstract Factory internally uses Factory Method to implement each create*() method.
Adding a new VARIANT to an Abstract Factory requires editing existing code.
Adding a new PRODUCT TYPE to an Abstract Factory requires editing existing code.
The client of an Abstract Factory must know all the concrete product class names to call factory.createX().
Abstract Factory and Singleton are often combined in practice.
Abstract Factory eliminates the need for the `new` keyword entirely in client code.

References

πŸ“š

Gamma, Helm, Johnson, Vlissides β€” Design Patterns: Elements of Reusable Object-Oriented Software (1995), Ch. 3, "Abstract Factory"

en.wikipedia.org

book
πŸ“„

Refactoring.guru β€” Abstract Factory Pattern

refactoring.guru

article
πŸ“„

Wikipedia β€” Abstract Factory Pattern

en.wikipedia.org

article
πŸ“š

Freeman, Robson, Bates, Sierra β€” Head First Design Patterns (2nd ed., 2020), Chapter 4: The Factory Pattern

oreilly.com

book
πŸ“‹

Oracle Javadoc β€” javax.xml.parsers.DocumentBuilderFactory (JDK Abstract Factory in the wild)

docs.oracle.com

docs