A combination of behavioural and creational design patterns to cater to the implementation of multiple providers.
Mon, May 18, 2026
2 min read

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:
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.

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.

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

let’s hop into the coding implementation of the strategy/factory:
interface IPaymentProvider {
pay(amount: number): void;
}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}`);
}
}interface IFactory {
get(provider: string): IPaymentProvider;
}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");
}
}
}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.