Factory Method Pattern: Payment Gateways

The Factory Method Pattern gives you a way to create objects without saying exactly which class will be used. It is helpful when your code needs to make different kinds of objects based on the situation, but you do not want it to know about all the details.

This pattern helps keep your code flexible, making it easy to add new types without changing old code. It is common in systems with plugins or many product types.

Real-Life Analogy: Payment Gateways

Imagine you run an online store. Customers can pay using different gateways: Stripe, PayPal, or Square. As the store owner, you don't care how each gateway works internally — you just want to process payments.

So, you create a base class with a ProcessPayment() method, and then have each gateway (Stripe, PayPal, Square) implement its own way to handle the transaction. The checkout system simply uses the interface, and the actual payment class is decided at runtime.

Different payment gateways processing transactions using a shared interface
Like switching between Stripe, PayPal, and Square, the Factory Method Pattern lets each subclass decide how to create the object — while keeping the interface consistent.

Benefits of Factory Method

By delegating object creation to subclasses, the Factory Method keeps your code clean and flexible. It helps reduce tight coupling between parts of your app and makes it easier to introduce new types without changing existing code.

Some advantages include:

  • Encapsulates object creation logic
  • Makes adding new types easier without touching existing code
  • Improves testability and maintainability

What to Implement

To implement the Factory Method pattern, you need:

  • Product Interface: An interface or abstract class that defines what all created objects should implement
  • Concrete Products: One or more classes that implement the product interface
  • Creator: An abstract class or interface that declares a Create method
  • Concrete Creators: Subclasses that implement the Create method and return specific product instances

How It Works in C#


// Product Interface
public interface IPaymentGateway
{
    void ProcessPayment(decimal amount);
}

// Concrete Products
public class StripeGateway : IPaymentGateway
{
    public void ProcessPayment(decimal amount) =>
        Console.WriteLine("Processing $" + amount + " through Stripe.");
}

public class PayPalGateway : IPaymentGateway
{
    public void ProcessPayment(decimal amount) =>
        Console.WriteLine("Processing $" + amount + " via PayPal.");
}

// Creator
public abstract class PaymentProcessor
{
    public abstract IPaymentGateway CreateGateway();
}

// Concrete Creators
public class StripeProcessor : PaymentProcessor
{
    public override IPaymentGateway CreateGateway() => new StripeGateway();
}

public class PayPalProcessor : PaymentProcessor
{
    public override IPaymentGateway CreateGateway() => new PayPalGateway();
}

Client code:


PaymentProcessor processor = new StripeProcessor();
IPaymentGateway gateway = processor.CreateGateway();
gateway.ProcessPayment(100);

When Should You Use It?

Many systems get cluttered with new keywords everywhere. This makes it hard to change how objects are created. The Factory Method gives you a better structure — especially when object creation varies by context.

Use it when:

  • You want to let subclasses decide which class to instantiate
  • You need flexibility to introduce new products
  • You want to reduce direct dependencies on concrete classes

When Not to Use It: Avoid it when your code is simple and object creation doesn't change. It may introduce unnecessary complexity.

Where Is It Used in the Real World?

The Factory Method Pattern is everywhere you want to defer object creation to subclasses. It is used in frameworks, plugin systems, and when switching between third-party integrations.

  • Framework extensibility (ASP.NET Core providers, logging)
  • Payment gateways and drivers
  • Document/graphic editors (creation of new document types)
  • Plugin and add-on systems

Final Thoughts

The Factory Method Pattern is like choosing the right payment processor at checkout. You don't need to rewrite your app for each gateway — just plug in a new one that follows the same rules.

This pattern helps you build flexible and scalable systems — especially when new types of products or behaviours may be added later.