Introduction

In this article, we will cover the Abstract Factory Design Pattern.

So, Let's get started.

Please refer to my previous article,

What is Abstract Factory?

The Abstract Factory is a creational design pattern that provides an interface for creating families of related objects without specifying their concrete classes. Think of it as a super factory that delegates object creation to specialized sub-factories based on your needs.

How do we implement the Abstract Factory Design Pattern in C#?

We must use the following components to Implement the Abstract Factory Design Pattern in C#.

Real-World Example. Payment Gateways in E-commerce

Let’s consider a scenario where financial software needs to process payments using different methods, such as “Credit Card” and “GPay”. The Abstract Factory pattern can help create families of related objects to process payments with each method, considering operations like payment authorization and transfer. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:

public interface IPaymentAuthorization
   {
      bool AuthorizePayment(decimal amount);
   }
public interface IPaymentTransfer
 {
    bool Transfer(decimal amount);
 }
// Concrete Products for Credit Card
public class CreditCardAuthorization : IPaymentAuthorization
 {
    public bool AuthorizePayment(decimal amount)
     {
        Console.WriteLine($"Authorizing payment of {amount} via Credit Card...");
         return true; // Mocked success
      }
 }
 public class CreditCardTransfer : IPaymentTransfer
    {
        public bool Transfer(decimal amount)
        {
            Console.WriteLine($"Transferring payment of {amount} via Credit Card...");
            return true; // Mocked success
        }
    }
// Concrete Products for GPay
 public class GPayAuthorization : IPaymentAuthorization
  {
     public bool AuthorizePayment(decimal amount)
      {
         Console.WriteLine($"Authorizing payment of {amount} via GPay...");
         return true; // Mocked success
      }
  }
 public class GPayTransfer : IPaymentTransfer
    {
        public bool Transfer(decimal amount)
        {
            Console.WriteLine($"Transferring payment of {amount} via GPay...");
            return true; // Mocked success
        }
    }
// Abstract Factory
public interface IPaymentFactory
 {
     IPaymentAuthorization CreateAuthorization();
     IPaymentTransfer CreateTransfer();
 }
// Concrete Factories
public class CreditCardPaymentFactory : IPaymentFactory
 {
    public IPaymentAuthorization CreateAuthorization() => new CreditCardAuthorization();
    public IPaymentTransfer CreateTransfer() => new CreditCardTransfer();
 }
public class GPayPaymentFactory : IPaymentFactory
 {
    public IPaymentAuthorization CreateAuthorization() => new GPayAuthorization();
    public IPaymentTransfer CreateTransfer() => new GPayTransfer();
 }
// Client Code
 public class PaymentProcessor
   {
     private readonly IPaymentAuthorization _authorization;
     private readonly IPaymentTransfer _transfer;
     
     public PaymentProcessor(IPaymentFactory factory)
      {
         _authorization = factory.CreateAuthorization();
         _transfer = factory.CreateTransfer();
      }
      
     public bool ProcessPayment(decimal amount)
       {
          if (_authorization.AuthorizePayment(amount))
           {
                return _transfer.Transfer(amount);
           }
          return false;
       }
   }
// Testing the Abstract Factory Design Pattern
public class Program
  {
	 public static void Main()
	  {
		 Console.WriteLine("Processing payment using Credit Card:");
            
         var creditCardFactory = new CreditCardPaymentFactory();
         var creditCardProcessor = new PaymentProcessor(creditCardFactory);
        
         creditCardProcessor.ProcessPayment(100.00M);
         Console.WriteLine("\nProcessing payment using GPay:");
      
         var gPayFactory = new GPayPaymentFactory();
         var gPayProcessor = new PaymentProcessor(gPayFactory);
         
         gPayProcessor.ProcessPayment(100.00M);
      
         Console.ReadKey();
      
	  }
  }

Output

Summary

In this article, I have tried to cover Abstract Factory Design Patterns.