LLD-strategy factory pattern

A combination of behavioural and creational design patterns to cater to the implementation of multiple providers.

user
Roshan Chaudhary

Mon, May 18, 2026

2 min read

thumbnail

combining strategy and factory pattern

The combination of strategy/factory pattern has some nuances with the traditional factory pattern(creational design pattern) and strategy pattern(behavioural pattern). In this practice, we tend to create a single object of the concrete class provider that we want to use according to the provider requested by the client.

Let's quickly jump into understanding what a strategy and factory pattern are:

Strategy pattern:

The strategy pattern falls under the behavioural design pattern. So, let's first understand what a behavioural pattern is. Behavioural design patterns focus on how objects communicate and collaborate to manage responsibilities effectively. Behavioural patterns promote loose coupling between components, improving system flexibility and maintainability.

Strategy pattern is a design pattern that defines concrete implementation of providers/services which are interchangeable according to the client's requirement.

image.png

Factory pattern

This pattern falls under the creational design pattern: It deals with creating objects and making the system independent of knowing the implementation of the classes.

Factory pattern defines an interface for creating an object, but lets the subclasses or client decide which object to create.

image.png

Here is what the UML diagram for the combination of strategy/factory pattern looks like:

strategy-factory.png

let’s hop into the coding implementation of the strategy/factory:

  • payment provider interface:
interface IPaymentProvider {
  pay(amount: number): void;
}
  • concrete provider/strategy implementation:
class EsewaProvider implements IPaymentProvider {
  pay(amount: number): void {
    console.log(`Processing eSewa payment of Rs.${amount}`);
  }
}
 
class KhaltiProvider implements IPaymentProvider {
  pay(amount: number): void {
    console.log(`Processing Khalti payment of Rs.${amount}`);
  }
}
 
class RazorpayProvider implements IPaymentProvider {
  pay(amount: number): void {
    console.log(`Processing Razorpay payment of Rs.${amount}`);
  }
}
  • factory interface:
interface IFactory {
  get(provider: string): IPaymentProvider;
}
  • Concrete payment factory:
class PaymentFactory implements IFactory {
 
  get(provider: string): IPaymentProvider {
 
    switch (provider.toLowerCase()) {
 
      case "esewa":
        return new EsewaProvider();
 
      case "khalti":
        return new KhaltiProvider();
 
      case "razorpay":
        return new RazorpayProvider();
 
      default:
        throw new Error("Invalid payment provider");
    }
  }
}

conclusion

This pattern is quite different from the abstract/factory pattern, where we tend to use the entire ecosystem of objects for UI’s, payment systems, etc.

Strategy/factory pattern can be used when we want to do a task, but with multiple ways according to the client's request. It can be used for payment systems, notification providers, logistic providers, etc.

Refrences

  1. https://www.geeksforgeeks.org/system-design/strategy-pattern-set-1/
  2. https://www.geeksforgeeks.org/system-design/factory-method-for-designing-pattern/
  3. https://www.geeksforgeeks.org/system-design/abstract-factory-pattern/
  4. https://www.geeksforgeeks.org/system-design/creational-design-pattern/