image de chargement
Back to glossary

Factory Pattern

Creational design pattern that provides an interface for creating objects without specifying their exact class, promoting decoupling and flexibility.

Updated on January 9, 2026

The Factory Pattern is a creational design pattern that delegates instantiation logic to a dedicated class or method, rather than using the 'new' operator directly. This pattern enables flexible object creation by encapsulating the complexity of instantiation and promoting the Single Responsibility Principle. It proves particularly valuable when the exact class of an object is determined at runtime or when multiple variants of the same object type must be created based on different contexts.

Pattern Fundamentals

  • Encapsulation of object creation logic within a dedicated method or class
  • Separation between creation interface and concrete class implementations
  • Adherence to the Open/Closed Principle: extensible without modifying existing client code
  • Abstraction of concrete dependencies in favor of interfaces or abstract classes

Business and Technical Benefits

  • Facilitates code evolution by centralizing creation logic in a single point
  • Reduces coupling between components, improving testability and maintainability
  • Enables addition of new object variants without impacting client code
  • Simplifies management of complex configurations or conditional dependencies
  • Enhances readability by making object creation intent explicit

Practical TypeScript Example

payment-factory.ts
// Common interface for all payment processors
interface PaymentProcessor {
  processPayment(amount: number): Promise<PaymentResult>;
  getProviderName(): string;
}

interface PaymentResult {
  success: boolean;
  transactionId: string;
}

// Concrete implementations
class StripeProcessor implements PaymentProcessor {
  async processPayment(amount: number): Promise<PaymentResult> {
    // Stripe logic
    return { success: true, transactionId: 'stripe_' + Date.now() };
  }
  getProviderName(): string { return 'Stripe'; }
}

class PayPalProcessor implements PaymentProcessor {
  async processPayment(amount: number): Promise<PaymentResult> {
    // PayPal logic
    return { success: true, transactionId: 'paypal_' + Date.now() };
  }
  getProviderName(): string { return 'PayPal'; }
}

class CryptoProcessor implements PaymentProcessor {
  async processPayment(amount: number): Promise<PaymentResult> {
    // Crypto logic
    return { success: true, transactionId: 'crypto_' + Date.now() };
  }
  getProviderName(): string { return 'Crypto'; }
}

// Factory
class PaymentProcessorFactory {
  static create(provider: 'stripe' | 'paypal' | 'crypto'): PaymentProcessor {
    switch (provider) {
      case 'stripe':
        return new StripeProcessor();
      case 'paypal':
        return new PayPalProcessor();
      case 'crypto':
        return new CryptoProcessor();
      default:
        throw new Error(`Provider ${provider} not supported`);
    }
  }
}

// Client code usage
const processor = PaymentProcessorFactory.create('stripe');
await processor.processPayment(99.99);

Effective Implementation

  1. Identify object families sharing a common interface or abstract class
  2. Create a factory method or class dedicated to instantiating these objects
  3. Implement selection logic based on parameters (type, configuration, context)
  4. Replace direct constructor calls with factory calls in client code
  5. Document available object types and their respective use cases
  6. Add unit tests to verify the factory returns correct instances

Pro Tip

Combine the Factory Pattern with dependency injection for even greater architectural flexibility. Register your factories in an IoC container, enabling dynamic strategy changes without modifying business logic. For complex applications, consider the Abstract Factory Pattern to manage families of related objects.

  • TypeScript with generic types for creating type-safe factories
  • InversifyJS or TSyringe for dependency injection with factory bindings
  • NestJS which natively integrates the pattern with custom providers
  • Factory Bot (Ruby) or Factory Boy (Python) for generating test fixtures
  • Builder Pattern as a complement for managing complex object construction

The Factory Pattern represents a strategic investment in code quality, significantly reducing long-term maintenance costs. By centralizing creation logic, it facilitates business evolution (adding new providers, product types) and improves test coverage by isolating dependencies. For modern teams, this pattern constitutes an essential building block of scalable architecture resilient to change.

Themoneyisalreadyonthetable.

In 1 hour, discover exactly how much you're losing and how to recover it.