---
name: abstract-factory
description: This skill should be used when the user asks about "abstract factory pattern", "factory of factories", "family of objects", "when to use abstract factory", "implement abstract factory", or mentions needing to create families of related objects.
version: 1.0.0
---

# Abstract Factory Pattern

## What Is It
The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It's essentially a "factory of factories" that ensures created objects work together.

## When to Use
- **Product families** - When you need to create sets of related objects that must work together
- **Cross-platform UI** - Different widget sets for Windows, macOS, Linux
- **Database abstraction** - Different connection, command, reader objects per database
- **Theme systems** - Consistent styling components (buttons, inputs, modals) per theme
- **Multi-tenant applications** - Different object families per tenant configuration
- **Testing** - Swap entire families of real objects with mock implementations

## When NOT to Use
- **Single product types** - Use Factory Method if you only need one product type
- **Unrelated products** - Products should have a logical relationship
- **Simple object creation** - Don't add complexity if direct instantiation works
- **Frequent new product types** - Adding new product types requires changing all factories

## How to Implement

### Implementation Steps
1. Define abstract product interfaces for each product type in the family
2. Create concrete product implementations for each variant
3. Define an abstract factory interface declaring creation methods for each product
4. Create concrete factory implementations for each product family
5. Client code uses abstract interfaces only

### TypeScript Implementation

```typescript
// Abstract products
interface Button { render(): string; }
interface Input { render(): string; }

// Concrete products - Light theme
class LightButton implements Button {
  render() { return 'Light button'; }
}
class LightInput implements Input {
  render() { return 'Light input'; }
}

// Concrete products - Dark theme
class DarkButton implements Button {
  render() { return 'Dark button'; }
}
class DarkInput implements Input {
  render() { return 'Dark input'; }
}

// Abstract factory
interface GUIFactory {
  createButton(): Button;
  createInput(): Input;
}

// Concrete factories
class LightThemeFactory implements GUIFactory {
  createButton(): Button { return new LightButton(); }
  createInput(): Input { return new LightInput(); }
}

class DarkThemeFactory implements GUIFactory {
  createButton(): Button { return new DarkButton(); }
  createInput(): Input { return new DarkInput(); }
}

// Usage
function buildUI(factory: GUIFactory) {
  const button = factory.createButton();
  const input = factory.createInput();
  console.log(button.render(), input.render());
}
```

## Code Examples
See `examples/` directory for runnable TypeScript implementations:
- `examples/abstract-factory.ts` - Basic implementation with furniture factory
- `examples/abstract-factory-advanced.ts` - Real-world example with database providers

## Related Patterns
- **Factory Method** - Often used within Abstract Factories to create products
- **Singleton** - Concrete factories are often Singletons
- **Prototype** - Can be combined to create factories that clone prototypes
- **Facade** - Abstract Factory can serve as a facade for creating subsystem objects
