Introduction
Abstract Factory Pattern is a creational design pattern that provides an interface for creating multiple or dependent objects without specifying their concrete classes.
It basically has:
An abstract factory interface that defines a set of methods for creating related objects.
Multiple concrete factory classes that implement this interface to create specific variants of those related objects.
A set of abstract interfaces or type definitions that define the contracts for the objects being created.
Multiple concrete implementations of those abstract types, organized into groups.
The Abstract Factory Pattern allows you to create related objects in a consistent way without tightly coupling code to specific concrete classes.
Prerequisites
Visual Studio 2022 installed
Basics of .NET
Source Code
The source code used in the example is publicly available on GitHub: Link
Why Do We Need Abstract Factory If We Already Have Factory Method?
The Factory Method Pattern defines a method for creating a single object, but it lets subclasses decide which concrete class to instantiate. Whereas, Abstract Factory provides an interface to create multiple related objects.
Step-by-Step Implementation with Real-World Example
Let’s say you’re building an e-commerce platform. You support Credit Card and PayPal.
Wait, it’s not that simple.
Each payment provider requires:
Payment Processor
Refund Processor
Transaction Logger
And here comes the important part:
If you choose Stripe, all related components must be Stripe-specific.
If you choose PayPal, everything must belong to PayPal.
If you write code in this way:
new StripePaymentProcessor()
new PayPalRefundProcessor()
Congratulations! You have mixed everything and will create code maintenance chaos as the system grows.
Can We Solve This Using Factory Method Pattern?
Factory Method works great if you create only one object.
public interface IPaymentProcessor
{
void Process(decimal amount);
}
And you create the object like this:
public class PaymentFactory
{
public static IPaymentProcessor Create(string provider)
{
return provider switch
{
"Stripe" => new StripePaymentProcessor(),
"PayPal" => new PayPalPaymentProcessor(),
_ => throw new ArgumentException()
};
}
}
This is nice, but you also need:
IRefundProcessor
ITransactionLogger
Now your factory becomes:
CreatePaymentProcessor()
CreateRefundProcessor()
CreateLogger()
And every method needs the same switch logic.
Implementing with Abstract Factory Pattern
Define the Abstract Contracts
public interface IPaymentProcessor
{
void Process(decimal amount);
}
public interface IRefundProcessor
{
void Refund(decimal amount);
}
public interface ITransactionLogger
{
void Log(string message);
}
Stripe Implementation
public class StripePaymentProcessor : IPaymentProcessor
{
public void Process(decimal amount)
{
Console.WriteLine($"[Stripe] Processing payment of {amount:C}");
}
}
public class StripeRefundProcessor : IRefundProcessor
{
public void Refund(decimal amount)
{
Console.WriteLine($"[Stripe] Refunding {amount:C}");
}
}
public class StripeTransactionLogger : ITransactionLogger
{
public void Log(string message)
{
Console.WriteLine($"[Stripe Log] {message}");
}
}


Join the conversation! Your thoughts help the community grow.