Abstract Factory Pattern
Provide an interface for creating families of related objects without specifying concrete classes.
📌 Key IdeaA super-factory (
AbstractFactory) defines methods for each product type in a family (e.g. WinButton + WinMenu). Swapping the concrete factory swaps the whole look-and-feel — not one class at a time. Often built from several Factory Methods.Why It Matters
- Consistency — Impossible to accidentally mix Win button with Mac menu from different factories.
- Swap themes — Change one factory reference → entire subsystem aesthetic updates.
- Encapsulation — Concrete class names stay inside factory implementations.
Visual
🎭 One factory → coordinated UI kit
Client only knows `UIFactory` — not Win vs Mac classes.
UIFactory f = new WinUIFactory(); Button b = f.createButton(); ScrollBar s = f.createScrollBar(); // Mac kit: new MacUIFactory() — same calls, different family.
Client depends on the abstract factory and abstract products — concrete kits plug in as one unit.
When to Use
- You need families of products that must be used together (UI themes, cross-platform toolkits, DB + driver + dialect).
- You want to switch an entire configuration (light vs dark theme, PostgreSQL vs MySQL stack).
- Construction rules are distributed — one place shouldn't know every concrete class name.
When NOT to Use
- Only one product varies — prefer Factory Method or plain DI.
- Families aren't coherent — you're really stacking unrelated singletons.
- Adding a new kind of product touches every concrete factory (classic Abstract Factory pain — sometimes Visitor or registry helps).
Anti-Pattern (What NOT to Do)
Client knows every concreteBadjava
void paint(boolean windows) {
Button b = windows ? new WinButton() : new MacButton();
Menu m = windows ? new WinMenu() : new MacMenu();
// New LinuxTheme? Edit every caller.Every switch duplicates; easy to pair mismatched widgets.
The Right Way
Inject abstract factoryGoodjava
interface ThemeFactory {
Button button();
Menu menu();
}
final class WinTheme implements ThemeFactory {
public Button button() { return new WinButton(); }
public Menu menu() { return new WinMenu(); }
}
// UI code only sees ThemeFactoryNew theme = new
ThemeFactory implementation — clients unchanged.Pros & Cons
👍 Pros
- Isolates concrete classes from the client.
- Promotes consistency among products in the same family.
- Works well with Dependency Injection (inject the factory).
👎 Cons
- Hard to add new product types — every concrete factory gains a method.
- Can explode into many interfaces if over-engineered.
Abstract Factory vs neighbours
| Aspect | Abstract Factory | Factory Method | Builder |
|---|---|---|---|
| Creates | Families of related products | One product kind via subclass | One complex object stepwise |
| Focus | Compatibility within a kit | Which subclass builds product | Optional parts / fluent API |
Common Confusions Cleared Up
Abstract Factory vs Factory Method
Factory Method is usually one abstract createProduct() on a Creator hierarchy. Abstract Factory is an interface with several createX() / createY() methods — each concrete factory implements all of them for one family.
Common Mistakes / Anti-Patterns
- One mega-factory with
if (os)for every method — use separate concrete factories. - Exposing concrete product classes from the abstract factory interface.
Interview Q&A
Likely Follow-up Questions
- How would you add a third product type to an existing Abstract Factory hierarchy?
- Abstract Factory vs Service Locator?
- Compare with Prototype when copying object graphs.
Quick Cheat Sheet
IntentFamilies of related objects; swap whole factory.
vs Factory MethodMany product kinds per factory vs one hook.
PainNew product type → touch all factories.
Often implements viaMultiple factory methods per concrete factory.