Back to: Design Patterns in C# With Real-Time Examples
Real-Time Examples of the Abstract Factory Design Pattern in C#
In this article, I will discuss the Real-Time Examples of the Abstract Factory Design Pattern in C#. Please read our previous article discussing the basic concepts of the Abstract Factory Design Pattern in C# with Examples. At the end of this article, you will understand the following Real-time Examples using the Abstract Factory Design Pattern in C#.
- Payment Gateways in E-commerce
- Cross-Platform UI Development
- Vehicle Manufacturing Company
- Cross-Platform Application Configuration
- Furniture Shop
- Managing Connections to Different Types of Databases
- Multi-Device User Interfaces
- Animal Kingdoms
- Multimedia Software
- Beverages
What is an Abstract Factory Design Pattern?
The Abstract Factory Design Pattern belongs to the Creational Design Pattern Category, and hence, it deals with Object Creation and Initialization. As discussed in our previous article, the Abstract Factory Design Pattern provides an interface for creating families of related or dependent objects without specifying their concrete class names. We can also say that Abstract Factory is a super factory or a factory of factories. That means it prevents the client from knowing which factory would be returned from the abstract factory.
How to implement the Abstract Factory Design Pattern in C#?
We must use the following components to Implement the Abstract Factory Design Pattern in C#.
- Abstract Product: These are going to be interfaces for creating abstract products. Here, we need to define the Operations a Product should have.
- Concrete Product: These are the classes that implement the Abstract Product interface.
- Abstract Factory: This will be an interface for operations that will create Abstract Product objects.
- Concrete Factory: These classes implement the Abstract Factory interface and provide implementations for the interface methods. We can use these concrete classes to create concrete product objects.
- Client: This class will use our Abstract Factory and Abstract Product interfaces to create a family of products.
To better understand how these components are integrated, please look at the following UML diagram of the Abstract Factory Design Pattern.

Real-Time Example of Abstract Factory Design Pattern in C#: 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 “PayPal”. 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#:
namespace AbstractFactoryDesignPattern
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 PayPal
public class PayPalAuthorization : IPaymentAuthorization
public bool AuthorizePayment(decimal amount)
Console.WriteLine($"Authorizing payment of {amount} via PayPal...");
return true; // Mocked success
public class PayPalTransfer : IPaymentTransfer
public bool Transfer(decimal amount)
Console.WriteLine($"Transferring payment of {amount} via PayPal...");
return true; // Mocked success
public interface IPaymentFactory
IPaymentAuthorization CreateAuthorization();
IPaymentTransfer CreateTransfer();
public class CreditCardPaymentFactory : IPaymentFactory
public IPaymentAuthorization CreateAuthorization() => new CreditCardAuthorization();
public IPaymentTransfer CreateTransfer() => new CreditCardTransfer();
public class PayPalPaymentFactory : IPaymentFactory
public IPaymentAuthorization CreateAuthorization() => new PayPalAuthorization();
public IPaymentTransfer CreateTransfer() => new PayPalTransfer();
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);
// Testing the Abstract Factory Design Pattern
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 PayPal:");
var payPalFactory = new PayPalPaymentFactory();
var payPalProcessor = new PaymentProcessor(payPalFactory);
payPalProcessor.ProcessPayment(100.00M);
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
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 PayPal
public class PayPalAuthorization : IPaymentAuthorization
{
public bool AuthorizePayment(decimal amount)
{
Console.WriteLine($"Authorizing payment of {amount} via PayPal...");
return true; // Mocked success
}
}
public class PayPalTransfer : IPaymentTransfer
{
public bool Transfer(decimal amount)
{
Console.WriteLine($"Transferring payment of {amount} via PayPal...");
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 PayPalPaymentFactory : IPaymentFactory
{
public IPaymentAuthorization CreateAuthorization() => new PayPalAuthorization();
public IPaymentTransfer CreateTransfer() => new PayPalTransfer();
}
// 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 PayPal:");
var payPalFactory = new PayPalPaymentFactory();
var payPalProcessor = new PaymentProcessor(payPalFactory);
payPalProcessor.ProcessPayment(100.00M);
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
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 PayPal
public class PayPalAuthorization : IPaymentAuthorization
{
public bool AuthorizePayment(decimal amount)
{
Console.WriteLine($"Authorizing payment of {amount} via PayPal...");
return true; // Mocked success
}
}
public class PayPalTransfer : IPaymentTransfer
{
public bool Transfer(decimal amount)
{
Console.WriteLine($"Transferring payment of {amount} via PayPal...");
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 PayPalPaymentFactory : IPaymentFactory
{
public IPaymentAuthorization CreateAuthorization() => new PayPalAuthorization();
public IPaymentTransfer CreateTransfer() => new PayPalTransfer();
}
// 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 PayPal:");
var payPalFactory = new PayPalPaymentFactory();
var payPalProcessor = new PaymentProcessor(payPalFactory);
payPalProcessor.ProcessPayment(100.00M);
Console.ReadKey();
}
}
}
In this example, the Abstract Factory pattern ensures that operations related to each payment method are cohesive and consistent. Each payment method’s authorization and transfer logic are kept separate, making extending the system with more payment methods in the future easier. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Cross-Platform UI Development
Suppose you’re building a cross-platform application that should run on Windows and MacOS. Both platforms have different styles for their UI elements. However, your application’s code should not care about which platform it’s running on. Instead, it should request the necessary UI elements and expect them to adhere to the platform’s conventions.
Using the Abstract Factory pattern, you can create an abstract factory layer that produces platform-specific UI elements. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface ITextBox
// Concrete Products for Windows
public class WindowsButton : IButton
Console.WriteLine("Windows Button Clicked");
public class WindowsTextBox : ITextBox
public void Write(string text)
Console.WriteLine($"Text Written in Windows TextBox: {text}");
// Concrete Products for MacOS
public class MacOSButton : IButton
Console.WriteLine("MacOS Button Clicked");
public class MacOSTextBox : ITextBox
public void Write(string text)
Console.WriteLine($"Text Written in MacOS TextBox: {text}");
public interface IUIFactory
ITextBox CreateTextBox();
// Concrete Factory for Windows
public class WindowsUIFactory : IUIFactory
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
// Concrete Factory for MacOS
public class MacOSUIFactory : IUIFactory
public IButton CreateButton() => new MacOSButton();
public ITextBox CreateTextBox() => new MacOSTextBox();
private readonly IButton _button;
private readonly ITextBox _textBox;
public Application(IUIFactory factory)
_button = factory.CreateButton();
_textBox = factory.CreateTextBox();
_textBox.Write("Sample Text");
// Testing the Abstract Factory Design Pattern
public static void Main()
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
factory = new WindowsUIFactory();
factory = new MacOSUIFactory();
var app = new Application(factory);
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IButton
{
void Click();
}
public interface ITextBox
{
void Write(string text);
}
// Concrete Products for Windows
public class WindowsButton : IButton
{
public void Click()
{
Console.WriteLine("Windows Button Clicked");
}
}
public class WindowsTextBox : ITextBox
{
public void Write(string text)
{
Console.WriteLine($"Text Written in Windows TextBox: {text}");
}
}
// Concrete Products for MacOS
public class MacOSButton : IButton
{
public void Click()
{
Console.WriteLine("MacOS Button Clicked");
}
}
public class MacOSTextBox : ITextBox
{
public void Write(string text)
{
Console.WriteLine($"Text Written in MacOS TextBox: {text}");
}
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
// Concrete Factory for Windows
public class WindowsUIFactory : IUIFactory
{
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
}
// Concrete Factory for MacOS
public class MacOSUIFactory : IUIFactory
{
public IButton CreateButton() => new MacOSButton();
public ITextBox CreateTextBox() => new MacOSTextBox();
}
// Client
public class Application
{
private readonly IButton _button;
private readonly ITextBox _textBox;
public Application(IUIFactory factory)
{
_button = factory.CreateButton();
_textBox = factory.CreateTextBox();
}
public void Render()
{
_button.Click();
_textBox.Write("Sample Text");
}
}
// Testing the Abstract Factory Design Pattern
// Client Code
public class Client
{
public static void Main()
{
IUIFactory factory;
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
factory = new WindowsUIFactory();
}
else
{
factory = new MacOSUIFactory();
}
var app = new Application(factory);
app.Render();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IButton
{
void Click();
}
public interface ITextBox
{
void Write(string text);
}
// Concrete Products for Windows
public class WindowsButton : IButton
{
public void Click()
{
Console.WriteLine("Windows Button Clicked");
}
}
public class WindowsTextBox : ITextBox
{
public void Write(string text)
{
Console.WriteLine($"Text Written in Windows TextBox: {text}");
}
}
// Concrete Products for MacOS
public class MacOSButton : IButton
{
public void Click()
{
Console.WriteLine("MacOS Button Clicked");
}
}
public class MacOSTextBox : ITextBox
{
public void Write(string text)
{
Console.WriteLine($"Text Written in MacOS TextBox: {text}");
}
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
}
// Concrete Factory for Windows
public class WindowsUIFactory : IUIFactory
{
public IButton CreateButton() => new WindowsButton();
public ITextBox CreateTextBox() => new WindowsTextBox();
}
// Concrete Factory for MacOS
public class MacOSUIFactory : IUIFactory
{
public IButton CreateButton() => new MacOSButton();
public ITextBox CreateTextBox() => new MacOSTextBox();
}
// Client
public class Application
{
private readonly IButton _button;
private readonly ITextBox _textBox;
public Application(IUIFactory factory)
{
_button = factory.CreateButton();
_textBox = factory.CreateTextBox();
}
public void Render()
{
_button.Click();
_textBox.Write("Sample Text");
}
}
// Testing the Abstract Factory Design Pattern
// Client Code
public class Client
{
public static void Main()
{
IUIFactory factory;
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
factory = new WindowsUIFactory();
}
else
{
factory = new MacOSUIFactory();
}
var app = new Application(factory);
app.Render();
Console.ReadKey();
}
}
}
In this example, when you run the application on a Windows machine, you’ll see the output tailored for Windows UI elements and similarly for MacOS. The actual decision-making about which UI elements to use is abstracted away using the Abstract Factory pattern. The application code asks the factory to give it a button or a text box without knowing how it looks or behaves on the underlying platform. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Vehicle Manufacturing Company
Let’s take the example of a vehicle manufacturing company that produces cars and trucks. These vehicles can either be electric or gas-powered. The company needs a system to create different parts (e.g., engine and tires) based on the type of vehicle and its power source. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
// Concrete Products for Electric Car
public class ElectricCarEngine : IEngine
public string GetEngineType()
return "Electric Car Engine";
public class ElectricCarTire : ITire
public string GetTireType()
return "Electric Car Tire";
// Concrete Products for Gas Car
public class GasCarEngine : IEngine
public string GetEngineType()
public class GasCarTire : ITire
public string GetTireType()
// Concrete Products for Electric Truck
public class ElectricTruckEngine : IEngine
public string GetEngineType()
return "Electric Truck Engine";
public class ElectricTruckTire : ITire
public string GetTireType()
return "Electric Truck Tire";
// Concrete Products for Gas Truck
public class GasTruckEngine : IEngine
public string GetEngineType()
return "Gas Truck Engine";
public class GasTruckTire : ITire
public string GetTireType()
public interface IVehicleFactory
public class ElectricCarFactory : IVehicleFactory
public IEngine CreateEngine() => new ElectricCarEngine();
public ITire CreateTire() => new ElectricCarTire();
public class GasCarFactory : IVehicleFactory
public IEngine CreateEngine() => new GasCarEngine();
public ITire CreateTire() => new GasCarTire();
public class ElectricTruckFactory : IVehicleFactory
public IEngine CreateEngine() => new ElectricTruckEngine();
public ITire CreateTire() => new ElectricTruckTire();
public class GasTruckFactory : IVehicleFactory
public IEngine CreateEngine() => new GasTruckEngine();
public ITire CreateTire() => new GasTruckTire();
public class VehicleManufacturingPlant
private readonly IEngine _engine;
private readonly ITire _tire;
public VehicleManufacturingPlant(IVehicleFactory factory)
_engine = factory.CreateEngine();
_tire = factory.CreateTire();
public void DescribeVehicle()
Console.WriteLine($"Vehicle with Engine: {_engine.GetEngineType()} and Tire: {_tire.GetTireType()}");
// Testing the Abstract Factory Design Pattern
public static void Main()
var electricCarFactory = new ElectricCarFactory();
var electricCarPlant = new VehicleManufacturingPlant(electricCarFactory);
electricCarPlant.DescribeVehicle();
var gasTruckFactory = new GasTruckFactory();
var gasTruckPlant = new VehicleManufacturingPlant(gasTruckFactory);
gasTruckPlant.DescribeVehicle();
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IEngine
{
string GetEngineType();
}
public interface ITire
{
string GetTireType();
}
// Concrete Products for Electric Car
public class ElectricCarEngine : IEngine
{
public string GetEngineType()
{
return "Electric Car Engine";
}
}
public class ElectricCarTire : ITire
{
public string GetTireType()
{
return "Electric Car Tire";
}
}
// Concrete Products for Gas Car
public class GasCarEngine : IEngine
{
public string GetEngineType()
{
return "Gas Car Engine";
}
}
public class GasCarTire : ITire
{
public string GetTireType()
{
return "Gas Car Tire";
}
}
// Concrete Products for Electric Truck
public class ElectricTruckEngine : IEngine
{
public string GetEngineType()
{
return "Electric Truck Engine";
}
}
public class ElectricTruckTire : ITire
{
public string GetTireType()
{
return "Electric Truck Tire";
}
}
// Concrete Products for Gas Truck
public class GasTruckEngine : IEngine
{
public string GetEngineType()
{
return "Gas Truck Engine";
}
}
public class GasTruckTire : ITire
{
public string GetTireType()
{
return "Gas Truck Tire";
}
}
// Abstract Factory
public interface IVehicleFactory
{
IEngine CreateEngine();
ITire CreateTire();
}
// Concrete Factories
public class ElectricCarFactory : IVehicleFactory
{
public IEngine CreateEngine() => new ElectricCarEngine();
public ITire CreateTire() => new ElectricCarTire();
}
public class GasCarFactory : IVehicleFactory
{
public IEngine CreateEngine() => new GasCarEngine();
public ITire CreateTire() => new GasCarTire();
}
public class ElectricTruckFactory : IVehicleFactory
{
public IEngine CreateEngine() => new ElectricTruckEngine();
public ITire CreateTire() => new ElectricTruckTire();
}
public class GasTruckFactory : IVehicleFactory
{
public IEngine CreateEngine() => new GasTruckEngine();
public ITire CreateTire() => new GasTruckTire();
}
// Client Code
public class VehicleManufacturingPlant
{
private readonly IEngine _engine;
private readonly ITire _tire;
public VehicleManufacturingPlant(IVehicleFactory factory)
{
_engine = factory.CreateEngine();
_tire = factory.CreateTire();
}
public void DescribeVehicle()
{
Console.WriteLine($"Vehicle with Engine: {_engine.GetEngineType()} and Tire: {_tire.GetTireType()}");
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
var electricCarFactory = new ElectricCarFactory();
var electricCarPlant = new VehicleManufacturingPlant(electricCarFactory);
electricCarPlant.DescribeVehicle();
var gasTruckFactory = new GasTruckFactory();
var gasTruckPlant = new VehicleManufacturingPlant(gasTruckFactory);
gasTruckPlant.DescribeVehicle();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IEngine
{
string GetEngineType();
}
public interface ITire
{
string GetTireType();
}
// Concrete Products for Electric Car
public class ElectricCarEngine : IEngine
{
public string GetEngineType()
{
return "Electric Car Engine";
}
}
public class ElectricCarTire : ITire
{
public string GetTireType()
{
return "Electric Car Tire";
}
}
// Concrete Products for Gas Car
public class GasCarEngine : IEngine
{
public string GetEngineType()
{
return "Gas Car Engine";
}
}
public class GasCarTire : ITire
{
public string GetTireType()
{
return "Gas Car Tire";
}
}
// Concrete Products for Electric Truck
public class ElectricTruckEngine : IEngine
{
public string GetEngineType()
{
return "Electric Truck Engine";
}
}
public class ElectricTruckTire : ITire
{
public string GetTireType()
{
return "Electric Truck Tire";
}
}
// Concrete Products for Gas Truck
public class GasTruckEngine : IEngine
{
public string GetEngineType()
{
return "Gas Truck Engine";
}
}
public class GasTruckTire : ITire
{
public string GetTireType()
{
return "Gas Truck Tire";
}
}
// Abstract Factory
public interface IVehicleFactory
{
IEngine CreateEngine();
ITire CreateTire();
}
// Concrete Factories
public class ElectricCarFactory : IVehicleFactory
{
public IEngine CreateEngine() => new ElectricCarEngine();
public ITire CreateTire() => new ElectricCarTire();
}
public class GasCarFactory : IVehicleFactory
{
public IEngine CreateEngine() => new GasCarEngine();
public ITire CreateTire() => new GasCarTire();
}
public class ElectricTruckFactory : IVehicleFactory
{
public IEngine CreateEngine() => new ElectricTruckEngine();
public ITire CreateTire() => new ElectricTruckTire();
}
public class GasTruckFactory : IVehicleFactory
{
public IEngine CreateEngine() => new GasTruckEngine();
public ITire CreateTire() => new GasTruckTire();
}
// Client Code
public class VehicleManufacturingPlant
{
private readonly IEngine _engine;
private readonly ITire _tire;
public VehicleManufacturingPlant(IVehicleFactory factory)
{
_engine = factory.CreateEngine();
_tire = factory.CreateTire();
}
public void DescribeVehicle()
{
Console.WriteLine($"Vehicle with Engine: {_engine.GetEngineType()} and Tire: {_tire.GetTireType()}");
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
var electricCarFactory = new ElectricCarFactory();
var electricCarPlant = new VehicleManufacturingPlant(electricCarFactory);
electricCarPlant.DescribeVehicle();
var gasTruckFactory = new GasTruckFactory();
var gasTruckPlant = new VehicleManufacturingPlant(gasTruckFactory);
gasTruckPlant.DescribeVehicle();
Console.ReadKey();
}
}
}
In this example, based on the chosen factory, the system produces vehicles with the appropriate engine and tire type. The Abstract Factory pattern abstracts away the complexities of creating families of related or dependent objects, allowing the client code to remain decoupled from the specific classes that are instantiated. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Cross-Platform Application Configuration
Imagine you’re developing a cross-platform application that will run on both Android and iOS. Each platform has its own unique settings, services, and notification mechanisms. You can utilize the Abstract Factory pattern to avoid tight coupling with platform-specific implementations. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface INotificationService
void Notify(string message);
public interface ISettings
string GetSetting(string key);
// Concrete Products for Android
public class AndroidNotificationService : INotificationService
public void Notify(string message)
Console.WriteLine($"Android notification: {message}");
public class AndroidSettings : ISettings
public string GetSetting(string key)
return $"Android setting value for {key}";
// Concrete Products for iOS
public class iOSNotificationService : INotificationService
public void Notify(string message)
Console.WriteLine($"iOS notification: {message}");
public class iOSSettings : ISettings
public string GetSetting(string key)
return $"iOS setting value for {key}";
public interface IPlatformFactory
INotificationService CreateNotificationService();
ISettings CreateSettings();
public class AndroidFactory : IPlatformFactory
public INotificationService CreateNotificationService() => new AndroidNotificationService();
public ISettings CreateSettings() => new AndroidSettings();
public class iOSFactory : IPlatformFactory
public INotificationService CreateNotificationService() => new iOSNotificationService();
public ISettings CreateSettings() => new iOSSettings();
public class ApplicationConfigurator
private readonly INotificationService _notificationService;
private readonly ISettings _settings;
public ApplicationConfigurator(IPlatformFactory factory)
_notificationService = factory.CreateNotificationService();
_settings = factory.CreateSettings();
public void RunSampleOperations()
string usernameSetting = _settings.GetSetting("Username");
Console.WriteLine($"Retrieved setting: {usernameSetting}");
_notificationService.Notify("App started!");
// Testing the Abstract Factory Design Pattern
public static void Main()
IPlatformFactory platformFactory;
if (Environment.OSVersion.Platform == PlatformID.Unix) // A simplistic way to distinguish, not accurate for all scenarios
platformFactory = new iOSFactory();
platformFactory = new AndroidFactory();
var appConfigurator = new ApplicationConfigurator(platformFactory);
appConfigurator.RunSampleOperations();
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface INotificationService
{
void Notify(string message);
}
public interface ISettings
{
string GetSetting(string key);
}
// Concrete Products for Android
public class AndroidNotificationService : INotificationService
{
public void Notify(string message)
{
Console.WriteLine($"Android notification: {message}");
}
}
public class AndroidSettings : ISettings
{
public string GetSetting(string key)
{
return $"Android setting value for {key}";
}
}
// Concrete Products for iOS
public class iOSNotificationService : INotificationService
{
public void Notify(string message)
{
Console.WriteLine($"iOS notification: {message}");
}
}
public class iOSSettings : ISettings
{
public string GetSetting(string key)
{
return $"iOS setting value for {key}";
}
}
// Abstract Factory
public interface IPlatformFactory
{
INotificationService CreateNotificationService();
ISettings CreateSettings();
}
// Concrete Factories
public class AndroidFactory : IPlatformFactory
{
public INotificationService CreateNotificationService() => new AndroidNotificationService();
public ISettings CreateSettings() => new AndroidSettings();
}
public class iOSFactory : IPlatformFactory
{
public INotificationService CreateNotificationService() => new iOSNotificationService();
public ISettings CreateSettings() => new iOSSettings();
}
// Client Code
public class ApplicationConfigurator
{
private readonly INotificationService _notificationService;
private readonly ISettings _settings;
public ApplicationConfigurator(IPlatformFactory factory)
{
_notificationService = factory.CreateNotificationService();
_settings = factory.CreateSettings();
}
public void RunSampleOperations()
{
string usernameSetting = _settings.GetSetting("Username");
Console.WriteLine($"Retrieved setting: {usernameSetting}");
_notificationService.Notify("App started!");
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
IPlatformFactory platformFactory;
if (Environment.OSVersion.Platform == PlatformID.Unix) // A simplistic way to distinguish, not accurate for all scenarios
{
platformFactory = new iOSFactory();
}
else
{
platformFactory = new AndroidFactory();
}
var appConfigurator = new ApplicationConfigurator(platformFactory);
appConfigurator.RunSampleOperations();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface INotificationService
{
void Notify(string message);
}
public interface ISettings
{
string GetSetting(string key);
}
// Concrete Products for Android
public class AndroidNotificationService : INotificationService
{
public void Notify(string message)
{
Console.WriteLine($"Android notification: {message}");
}
}
public class AndroidSettings : ISettings
{
public string GetSetting(string key)
{
return $"Android setting value for {key}";
}
}
// Concrete Products for iOS
public class iOSNotificationService : INotificationService
{
public void Notify(string message)
{
Console.WriteLine($"iOS notification: {message}");
}
}
public class iOSSettings : ISettings
{
public string GetSetting(string key)
{
return $"iOS setting value for {key}";
}
}
// Abstract Factory
public interface IPlatformFactory
{
INotificationService CreateNotificationService();
ISettings CreateSettings();
}
// Concrete Factories
public class AndroidFactory : IPlatformFactory
{
public INotificationService CreateNotificationService() => new AndroidNotificationService();
public ISettings CreateSettings() => new AndroidSettings();
}
public class iOSFactory : IPlatformFactory
{
public INotificationService CreateNotificationService() => new iOSNotificationService();
public ISettings CreateSettings() => new iOSSettings();
}
// Client Code
public class ApplicationConfigurator
{
private readonly INotificationService _notificationService;
private readonly ISettings _settings;
public ApplicationConfigurator(IPlatformFactory factory)
{
_notificationService = factory.CreateNotificationService();
_settings = factory.CreateSettings();
}
public void RunSampleOperations()
{
string usernameSetting = _settings.GetSetting("Username");
Console.WriteLine($"Retrieved setting: {usernameSetting}");
_notificationService.Notify("App started!");
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
IPlatformFactory platformFactory;
if (Environment.OSVersion.Platform == PlatformID.Unix) // A simplistic way to distinguish, not accurate for all scenarios
{
platformFactory = new iOSFactory();
}
else
{
platformFactory = new AndroidFactory();
}
var appConfigurator = new ApplicationConfigurator(platformFactory);
appConfigurator.RunSampleOperations();
Console.ReadKey();
}
}
}
In this real-time example, the Abstract Factory pattern allows us to abstract away platform-specific details from our main application. This promotes the separation of concerns and makes the code more modular and easier to extend when adding support for new platforms. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Furniture Shop
Let’s see another real-world example: a furniture shop offering modern and vintage products. We will use the Abstract Factory pattern to produce related furniture objects for different styles without specifying the exact classes to create. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
// Concrete Products for Modern Style
public class ModernChair : IChair
Console.WriteLine("Sitting on a modern chair.");
public class ModernSofa : ISofa
Console.WriteLine("Laying on a modern sofa.");
// Concrete Products for Vintage Style
public class VintageChair : IChair
Console.WriteLine("Sitting on a vintage chair.");
public class VintageSofa : ISofa
Console.WriteLine("Laying on a vintage sofa.");
public interface IFurnitureFactory
public class ModernFurnitureFactory : IFurnitureFactory
public IChair CreateChair() => new ModernChair();
public ISofa CreateSofa() => new ModernSofa();
public class VintageFurnitureFactory : IFurnitureFactory
public IChair CreateChair() => new VintageChair();
public ISofa CreateSofa() => new VintageSofa();
public class FurnitureShop
private readonly IChair _chair;
private readonly ISofa _sofa;
public FurnitureShop(IFurnitureFactory factory)
_chair = factory.CreateChair();
_sofa = factory.CreateSofa();
public void ShowProducts()
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Order for Modern Furniture:");
var modernFactory = new ModernFurnitureFactory();
var modernShop = new FurnitureShop(modernFactory);
modernShop.ShowProducts();
Console.WriteLine("\nOrder for Vintage Furniture:");
var vintageFactory = new VintageFurnitureFactory();
var vintageShop = new FurnitureShop(vintageFactory);
vintageShop.ShowProducts();
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IChair
{
void SitOn();
}
public interface ISofa
{
void LayOn();
}
// Concrete Products for Modern Style
public class ModernChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a modern chair.");
}
}
public class ModernSofa : ISofa
{
public void LayOn()
{
Console.WriteLine("Laying on a modern sofa.");
}
}
// Concrete Products for Vintage Style
public class VintageChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a vintage chair.");
}
}
public class VintageSofa : ISofa
{
public void LayOn()
{
Console.WriteLine("Laying on a vintage sofa.");
}
}
// Abstract Factory
public interface IFurnitureFactory
{
IChair CreateChair();
ISofa CreateSofa();
}
// Concrete Factories
public class ModernFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair() => new ModernChair();
public ISofa CreateSofa() => new ModernSofa();
}
public class VintageFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair() => new VintageChair();
public ISofa CreateSofa() => new VintageSofa();
}
// Client Code
public class FurnitureShop
{
private readonly IChair _chair;
private readonly ISofa _sofa;
public FurnitureShop(IFurnitureFactory factory)
{
_chair = factory.CreateChair();
_sofa = factory.CreateSofa();
}
public void ShowProducts()
{
_chair.SitOn();
_sofa.LayOn();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Order for Modern Furniture:");
var modernFactory = new ModernFurnitureFactory();
var modernShop = new FurnitureShop(modernFactory);
modernShop.ShowProducts();
Console.WriteLine("\nOrder for Vintage Furniture:");
var vintageFactory = new VintageFurnitureFactory();
var vintageShop = new FurnitureShop(vintageFactory);
vintageShop.ShowProducts();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IChair
{
void SitOn();
}
public interface ISofa
{
void LayOn();
}
// Concrete Products for Modern Style
public class ModernChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a modern chair.");
}
}
public class ModernSofa : ISofa
{
public void LayOn()
{
Console.WriteLine("Laying on a modern sofa.");
}
}
// Concrete Products for Vintage Style
public class VintageChair : IChair
{
public void SitOn()
{
Console.WriteLine("Sitting on a vintage chair.");
}
}
public class VintageSofa : ISofa
{
public void LayOn()
{
Console.WriteLine("Laying on a vintage sofa.");
}
}
// Abstract Factory
public interface IFurnitureFactory
{
IChair CreateChair();
ISofa CreateSofa();
}
// Concrete Factories
public class ModernFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair() => new ModernChair();
public ISofa CreateSofa() => new ModernSofa();
}
public class VintageFurnitureFactory : IFurnitureFactory
{
public IChair CreateChair() => new VintageChair();
public ISofa CreateSofa() => new VintageSofa();
}
// Client Code
public class FurnitureShop
{
private readonly IChair _chair;
private readonly ISofa _sofa;
public FurnitureShop(IFurnitureFactory factory)
{
_chair = factory.CreateChair();
_sofa = factory.CreateSofa();
}
public void ShowProducts()
{
_chair.SitOn();
_sofa.LayOn();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Order for Modern Furniture:");
var modernFactory = new ModernFurnitureFactory();
var modernShop = new FurnitureShop(modernFactory);
modernShop.ShowProducts();
Console.WriteLine("\nOrder for Vintage Furniture:");
var vintageFactory = new VintageFurnitureFactory();
var vintageShop = new FurnitureShop(vintageFactory);
vintageShop.ShowProducts();
Console.ReadKey();
}
}
}
In this example, based on the chosen factory (Modern or Vintage), the furniture shop produces the furniture products accordingly. The Abstract Factory pattern ensures that the families of related products (in this case, furniture) are consistently created, ensuring that you won’t accidentally mix modern chairs with vintage sofas, for instance. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Managing Connections to Different Types of Databases
Let’s understand another real-time scenario: managing connections to different types of databases like SQL Server and Oracle. In a large organization, various applications might need different types of database connections, but they all require certain operations like “ExecuteCommand” and “CreateConnection”. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface ICommand
void Execute(string query);
public interface IConnection
// Concrete Products for SQL Server
public class SQLServerCommand : ICommand
public void Execute(string query)
Console.WriteLine($"SQL Server executing command: {query}");
public class SQLServerConnection : IConnection
public void OpenConnection()
Console.WriteLine("SQL Server connection opened.");
// Concrete Products for Oracle
public class OracleCommand : ICommand
public void Execute(string query)
Console.WriteLine($"Oracle executing command: {query}");
public class OracleConnection : IConnection
public void OpenConnection()
Console.WriteLine("Oracle connection opened.");
public interface IDatabaseFactory
ICommand CreateCommand();
IConnection CreateConnection();
public class SQLServerFactory : IDatabaseFactory
public ICommand CreateCommand() => new SQLServerCommand();
public IConnection CreateConnection() => new SQLServerConnection();
public class OracleFactory : IDatabaseFactory
public ICommand CreateCommand() => new OracleCommand();
public IConnection CreateConnection() => new OracleConnection();
public class DatabaseManager
private readonly ICommand _command;
private readonly IConnection _connection;
public DatabaseManager(IDatabaseFactory factory)
_command = factory.CreateCommand();
_connection = factory.CreateConnection();
public void PerformDatabaseOperations(string query)
_connection.OpenConnection();
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Using SQL Server:");
var sqlFactory = new SQLServerFactory();
var sqlManager = new DatabaseManager(sqlFactory);
sqlManager.PerformDatabaseOperations("SELECT * FROM Users");
Console.WriteLine("\nUsing Oracle:");
var oracleFactory = new OracleFactory();
var oracleManager = new DatabaseManager(oracleFactory);
oracleManager.PerformDatabaseOperations("SELECT * FROM Employees");
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface ICommand
{
void Execute(string query);
}
public interface IConnection
{
void OpenConnection();
}
// Concrete Products for SQL Server
public class SQLServerCommand : ICommand
{
public void Execute(string query)
{
Console.WriteLine($"SQL Server executing command: {query}");
}
}
public class SQLServerConnection : IConnection
{
public void OpenConnection()
{
Console.WriteLine("SQL Server connection opened.");
}
}
// Concrete Products for Oracle
public class OracleCommand : ICommand
{
public void Execute(string query)
{
Console.WriteLine($"Oracle executing command: {query}");
}
}
public class OracleConnection : IConnection
{
public void OpenConnection()
{
Console.WriteLine("Oracle connection opened.");
}
}
// Abstract Factory
public interface IDatabaseFactory
{
ICommand CreateCommand();
IConnection CreateConnection();
}
// Concrete Factories
public class SQLServerFactory : IDatabaseFactory
{
public ICommand CreateCommand() => new SQLServerCommand();
public IConnection CreateConnection() => new SQLServerConnection();
}
public class OracleFactory : IDatabaseFactory
{
public ICommand CreateCommand() => new OracleCommand();
public IConnection CreateConnection() => new OracleConnection();
}
// Client Code
public class DatabaseManager
{
private readonly ICommand _command;
private readonly IConnection _connection;
public DatabaseManager(IDatabaseFactory factory)
{
_command = factory.CreateCommand();
_connection = factory.CreateConnection();
}
public void PerformDatabaseOperations(string query)
{
_connection.OpenConnection();
_command.Execute(query);
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Using SQL Server:");
var sqlFactory = new SQLServerFactory();
var sqlManager = new DatabaseManager(sqlFactory);
sqlManager.PerformDatabaseOperations("SELECT * FROM Users");
Console.WriteLine("\nUsing Oracle:");
var oracleFactory = new OracleFactory();
var oracleManager = new DatabaseManager(oracleFactory);
oracleManager.PerformDatabaseOperations("SELECT * FROM Employees");
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface ICommand
{
void Execute(string query);
}
public interface IConnection
{
void OpenConnection();
}
// Concrete Products for SQL Server
public class SQLServerCommand : ICommand
{
public void Execute(string query)
{
Console.WriteLine($"SQL Server executing command: {query}");
}
}
public class SQLServerConnection : IConnection
{
public void OpenConnection()
{
Console.WriteLine("SQL Server connection opened.");
}
}
// Concrete Products for Oracle
public class OracleCommand : ICommand
{
public void Execute(string query)
{
Console.WriteLine($"Oracle executing command: {query}");
}
}
public class OracleConnection : IConnection
{
public void OpenConnection()
{
Console.WriteLine("Oracle connection opened.");
}
}
// Abstract Factory
public interface IDatabaseFactory
{
ICommand CreateCommand();
IConnection CreateConnection();
}
// Concrete Factories
public class SQLServerFactory : IDatabaseFactory
{
public ICommand CreateCommand() => new SQLServerCommand();
public IConnection CreateConnection() => new SQLServerConnection();
}
public class OracleFactory : IDatabaseFactory
{
public ICommand CreateCommand() => new OracleCommand();
public IConnection CreateConnection() => new OracleConnection();
}
// Client Code
public class DatabaseManager
{
private readonly ICommand _command;
private readonly IConnection _connection;
public DatabaseManager(IDatabaseFactory factory)
{
_command = factory.CreateCommand();
_connection = factory.CreateConnection();
}
public void PerformDatabaseOperations(string query)
{
_connection.OpenConnection();
_command.Execute(query);
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Using SQL Server:");
var sqlFactory = new SQLServerFactory();
var sqlManager = new DatabaseManager(sqlFactory);
sqlManager.PerformDatabaseOperations("SELECT * FROM Users");
Console.WriteLine("\nUsing Oracle:");
var oracleFactory = new OracleFactory();
var oracleManager = new DatabaseManager(oracleFactory);
oracleManager.PerformDatabaseOperations("SELECT * FROM Employees");
Console.ReadKey();
}
}
}
In this real-time example, the Abstract Factory pattern consistently creates related database objects (connection and command) without directly tying the code to a specific database implementation. This approach makes it easier to add support for new databases in the future, ensuring flexibility and maintainability. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Multi-Device User Interfaces
Let’s understand another real-world scenario: creating multi-device user interfaces for mobile and desktop platforms. As the application grows, there might be a need to create consistent user interfaces for different devices.
The Abstract Factory pattern is handy here to ensure the creation of consistent UI elements across these devices. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
// Concrete Products for Mobile
public class MobileButton : IButton
Console.WriteLine("Rendering a mobile button.");
public class MobileMenu : IMenu
Console.WriteLine("Displaying a mobile menu.");
// Concrete Products for Desktop
public class DesktopButton : IButton
Console.WriteLine("Rendering a desktop button.");
public class DesktopMenu : IMenu
Console.WriteLine("Displaying a desktop menu.");
public interface IUIFactory
public class MobileUIFactory : IUIFactory
public IButton CreateButton() => new MobileButton();
public IMenu CreateMenu() => new MobileMenu();
public class DesktopUIFactory : IUIFactory
public IButton CreateButton() => new DesktopButton();
public IMenu CreateMenu() => new DesktopMenu();
public class UserInterface
private readonly IButton _button;
private readonly IMenu _menu;
public UserInterface(IUIFactory factory)
_button = factory.CreateButton();
_menu = factory.CreateMenu();
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Creating UI for Mobile:");
var mobileFactory = new MobileUIFactory();
var mobileUI = new UserInterface(mobileFactory);
Console.WriteLine("\nCreating UI for Desktop:");
var desktopFactory = new DesktopUIFactory();
var desktopUI = new UserInterface(desktopFactory);
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IButton
{
void Render();
}
public interface IMenu
{
void Display();
}
// Concrete Products for Mobile
public class MobileButton : IButton
{
public void Render()
{
Console.WriteLine("Rendering a mobile button.");
}
}
public class MobileMenu : IMenu
{
public void Display()
{
Console.WriteLine("Displaying a mobile menu.");
}
}
// Concrete Products for Desktop
public class DesktopButton : IButton
{
public void Render()
{
Console.WriteLine("Rendering a desktop button.");
}
}
public class DesktopMenu : IMenu
{
public void Display()
{
Console.WriteLine("Displaying a desktop menu.");
}
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
IMenu CreateMenu();
}
// Concrete Factories
public class MobileUIFactory : IUIFactory
{
public IButton CreateButton() => new MobileButton();
public IMenu CreateMenu() => new MobileMenu();
}
public class DesktopUIFactory : IUIFactory
{
public IButton CreateButton() => new DesktopButton();
public IMenu CreateMenu() => new DesktopMenu();
}
// Client Code
public class UserInterface
{
private readonly IButton _button;
private readonly IMenu _menu;
public UserInterface(IUIFactory factory)
{
_button = factory.CreateButton();
_menu = factory.CreateMenu();
}
public void RenderUI()
{
_button.Render();
_menu.Display();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Creating UI for Mobile:");
var mobileFactory = new MobileUIFactory();
var mobileUI = new UserInterface(mobileFactory);
mobileUI.RenderUI();
Console.WriteLine("\nCreating UI for Desktop:");
var desktopFactory = new DesktopUIFactory();
var desktopUI = new UserInterface(desktopFactory);
desktopUI.RenderUI();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IButton
{
void Render();
}
public interface IMenu
{
void Display();
}
// Concrete Products for Mobile
public class MobileButton : IButton
{
public void Render()
{
Console.WriteLine("Rendering a mobile button.");
}
}
public class MobileMenu : IMenu
{
public void Display()
{
Console.WriteLine("Displaying a mobile menu.");
}
}
// Concrete Products for Desktop
public class DesktopButton : IButton
{
public void Render()
{
Console.WriteLine("Rendering a desktop button.");
}
}
public class DesktopMenu : IMenu
{
public void Display()
{
Console.WriteLine("Displaying a desktop menu.");
}
}
// Abstract Factory
public interface IUIFactory
{
IButton CreateButton();
IMenu CreateMenu();
}
// Concrete Factories
public class MobileUIFactory : IUIFactory
{
public IButton CreateButton() => new MobileButton();
public IMenu CreateMenu() => new MobileMenu();
}
public class DesktopUIFactory : IUIFactory
{
public IButton CreateButton() => new DesktopButton();
public IMenu CreateMenu() => new DesktopMenu();
}
// Client Code
public class UserInterface
{
private readonly IButton _button;
private readonly IMenu _menu;
public UserInterface(IUIFactory factory)
{
_button = factory.CreateButton();
_menu = factory.CreateMenu();
}
public void RenderUI()
{
_button.Render();
_menu.Display();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Creating UI for Mobile:");
var mobileFactory = new MobileUIFactory();
var mobileUI = new UserInterface(mobileFactory);
mobileUI.RenderUI();
Console.WriteLine("\nCreating UI for Desktop:");
var desktopFactory = new DesktopUIFactory();
var desktopUI = new UserInterface(desktopFactory);
desktopUI.RenderUI();
Console.ReadKey();
}
}
}
When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Animal Kingdoms
Let’s understand another example involving animal kingdoms. Consider that you are building a simulation where animals from different regions (e.g., “Jungle” and “Arctic”) interact with their environment.
Different regions have different types of herbivores and carnivores. The Abstract Factory Pattern will be handy to ensure that the system can easily instantiate families of related animal objects based on the region. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface IHerbivore
public interface ICarnivore
// Concrete Products for Jungle
public class Deer : IHerbivore
Console.WriteLine("Deer is grazing.");
public class Tiger : ICarnivore
Console.WriteLine("Tiger is hunting.");
// Concrete Products for Arctic
public class Reindeer : IHerbivore
Console.WriteLine("Reindeer is grazing.");
public class PolarBear : ICarnivore
Console.WriteLine("Polar bear is hunting.");
public interface IAnimalFactory
IHerbivore CreateHerbivore();
ICarnivore CreateCarnivore();
public class JungleAnimalFactory : IAnimalFactory
public IHerbivore CreateHerbivore() => new Deer();
public ICarnivore CreateCarnivore() => new Tiger();
public class ArcticAnimalFactory : IAnimalFactory
public IHerbivore CreateHerbivore() => new Reindeer();
public ICarnivore CreateCarnivore() => new PolarBear();
private readonly IHerbivore _herbivore;
private readonly ICarnivore _carnivore;
public Ecosystem(IAnimalFactory factory)
_herbivore = factory.CreateHerbivore();
_carnivore = factory.CreateCarnivore();
public void RunFoodChain()
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Jungle Ecosystem:");
var jungleFactory = new JungleAnimalFactory();
var jungle = new Ecosystem(jungleFactory);
Console.WriteLine("\nArctic Ecosystem:");
var arcticFactory = new ArcticAnimalFactory();
var arctic = new Ecosystem(arcticFactory);
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IHerbivore
{
void Graze();
}
public interface ICarnivore
{
void Hunt();
}
// Concrete Products for Jungle
public class Deer : IHerbivore
{
public void Graze()
{
Console.WriteLine("Deer is grazing.");
}
}
public class Tiger : ICarnivore
{
public void Hunt()
{
Console.WriteLine("Tiger is hunting.");
}
}
// Concrete Products for Arctic
public class Reindeer : IHerbivore
{
public void Graze()
{
Console.WriteLine("Reindeer is grazing.");
}
}
public class PolarBear : ICarnivore
{
public void Hunt()
{
Console.WriteLine("Polar bear is hunting.");
}
}
// Abstract Factory
public interface IAnimalFactory
{
IHerbivore CreateHerbivore();
ICarnivore CreateCarnivore();
}
// Concrete Factories
public class JungleAnimalFactory : IAnimalFactory
{
public IHerbivore CreateHerbivore() => new Deer();
public ICarnivore CreateCarnivore() => new Tiger();
}
public class ArcticAnimalFactory : IAnimalFactory
{
public IHerbivore CreateHerbivore() => new Reindeer();
public ICarnivore CreateCarnivore() => new PolarBear();
}
// Client Code
public class Ecosystem
{
private readonly IHerbivore _herbivore;
private readonly ICarnivore _carnivore;
public Ecosystem(IAnimalFactory factory)
{
_herbivore = factory.CreateHerbivore();
_carnivore = factory.CreateCarnivore();
}
public void RunFoodChain()
{
_herbivore.Graze();
_carnivore.Hunt();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Jungle Ecosystem:");
var jungleFactory = new JungleAnimalFactory();
var jungle = new Ecosystem(jungleFactory);
jungle.RunFoodChain();
Console.WriteLine("\nArctic Ecosystem:");
var arcticFactory = new ArcticAnimalFactory();
var arctic = new Ecosystem(arcticFactory);
arctic.RunFoodChain();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IHerbivore
{
void Graze();
}
public interface ICarnivore
{
void Hunt();
}
// Concrete Products for Jungle
public class Deer : IHerbivore
{
public void Graze()
{
Console.WriteLine("Deer is grazing.");
}
}
public class Tiger : ICarnivore
{
public void Hunt()
{
Console.WriteLine("Tiger is hunting.");
}
}
// Concrete Products for Arctic
public class Reindeer : IHerbivore
{
public void Graze()
{
Console.WriteLine("Reindeer is grazing.");
}
}
public class PolarBear : ICarnivore
{
public void Hunt()
{
Console.WriteLine("Polar bear is hunting.");
}
}
// Abstract Factory
public interface IAnimalFactory
{
IHerbivore CreateHerbivore();
ICarnivore CreateCarnivore();
}
// Concrete Factories
public class JungleAnimalFactory : IAnimalFactory
{
public IHerbivore CreateHerbivore() => new Deer();
public ICarnivore CreateCarnivore() => new Tiger();
}
public class ArcticAnimalFactory : IAnimalFactory
{
public IHerbivore CreateHerbivore() => new Reindeer();
public ICarnivore CreateCarnivore() => new PolarBear();
}
// Client Code
public class Ecosystem
{
private readonly IHerbivore _herbivore;
private readonly ICarnivore _carnivore;
public Ecosystem(IAnimalFactory factory)
{
_herbivore = factory.CreateHerbivore();
_carnivore = factory.CreateCarnivore();
}
public void RunFoodChain()
{
_herbivore.Graze();
_carnivore.Hunt();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Jungle Ecosystem:");
var jungleFactory = new JungleAnimalFactory();
var jungle = new Ecosystem(jungleFactory);
jungle.RunFoodChain();
Console.WriteLine("\nArctic Ecosystem:");
var arcticFactory = new ArcticAnimalFactory();
var arctic = new Ecosystem(arcticFactory);
arctic.RunFoodChain();
Console.ReadKey();
}
}
}
In this example, the Abstract Factory pattern facilitates the instantiation of related animals (herbivores and carnivores) specific to a region (Jungle or Arctic). This organization ensures flexibility, allowing for adding new regions and associated animals easily. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Multimedia Software
Let’s understand another example of a multimedia software suite that supports audio and video. Depending on the user’s needs, the software can use different formats, e.g., MP3 vs. WAV for audio and MP4 vs. AVI for video.
The Abstract Factory pattern can ensure that once a format is chosen, consistent audio and video processing tools are provided for that format. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface IAudioProcessor
void ProcessAudio(string file);
public interface IVideoProcessor
void ProcessVideo(string file);
// Concrete Products for MP3 & MP4
public class MP3Processor : IAudioProcessor
public void ProcessAudio(string file)
Console.WriteLine($"Processing MP3 audio file: {file}");
public class MP4Processor : IVideoProcessor
public void ProcessVideo(string file)
Console.WriteLine($"Processing MP4 video file: {file}");
// Concrete Products for WAV & AVI
public class WAVProcessor : IAudioProcessor
public void ProcessAudio(string file)
Console.WriteLine($"Processing WAV audio file: {file}");
public class AVIProcessor : IVideoProcessor
public void ProcessVideo(string file)
Console.WriteLine($"Processing AVI video file: {file}");
public interface IMediaFactory
IAudioProcessor CreateAudioProcessor();
IVideoProcessor CreateVideoProcessor();
public class MP3MP4Factory : IMediaFactory
public IAudioProcessor CreateAudioProcessor() => new MP3Processor();
public IVideoProcessor CreateVideoProcessor() => new MP4Processor();
public class WAVAVIFactory : IMediaFactory
public IAudioProcessor CreateAudioProcessor() => new WAVProcessor();
public IVideoProcessor CreateVideoProcessor() => new AVIProcessor();
public class MediaApplication
private readonly IAudioProcessor _audioProcessor;
private readonly IVideoProcessor _videoProcessor;
public MediaApplication(IMediaFactory factory)
_audioProcessor = factory.CreateAudioProcessor();
_videoProcessor = factory.CreateVideoProcessor();
public void Run(string audioFile, string videoFile)
_audioProcessor.ProcessAudio(audioFile);
_videoProcessor.ProcessVideo(videoFile);
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Using MP3 & MP4 formats:");
var mp3mp4Factory = new MP3MP4Factory();
var mp3mp4App = new MediaApplication(mp3mp4Factory);
mp3mp4App.Run("song.mp3", "video.mp4");
Console.WriteLine("\nUsing WAV & AVI formats:");
var wavaviFactory = new WAVAVIFactory();
var wavaviApp = new MediaApplication(wavaviFactory);
wavaviApp.Run("song.wav", "video.avi");
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IAudioProcessor
{
void ProcessAudio(string file);
}
public interface IVideoProcessor
{
void ProcessVideo(string file);
}
// Concrete Products for MP3 & MP4
public class MP3Processor : IAudioProcessor
{
public void ProcessAudio(string file)
{
Console.WriteLine($"Processing MP3 audio file: {file}");
}
}
public class MP4Processor : IVideoProcessor
{
public void ProcessVideo(string file)
{
Console.WriteLine($"Processing MP4 video file: {file}");
}
}
// Concrete Products for WAV & AVI
public class WAVProcessor : IAudioProcessor
{
public void ProcessAudio(string file)
{
Console.WriteLine($"Processing WAV audio file: {file}");
}
}
public class AVIProcessor : IVideoProcessor
{
public void ProcessVideo(string file)
{
Console.WriteLine($"Processing AVI video file: {file}");
}
}
// Abstract Factory
public interface IMediaFactory
{
IAudioProcessor CreateAudioProcessor();
IVideoProcessor CreateVideoProcessor();
}
// Concrete Factories
public class MP3MP4Factory : IMediaFactory
{
public IAudioProcessor CreateAudioProcessor() => new MP3Processor();
public IVideoProcessor CreateVideoProcessor() => new MP4Processor();
}
public class WAVAVIFactory : IMediaFactory
{
public IAudioProcessor CreateAudioProcessor() => new WAVProcessor();
public IVideoProcessor CreateVideoProcessor() => new AVIProcessor();
}
// Client Code
public class MediaApplication
{
private readonly IAudioProcessor _audioProcessor;
private readonly IVideoProcessor _videoProcessor;
public MediaApplication(IMediaFactory factory)
{
_audioProcessor = factory.CreateAudioProcessor();
_videoProcessor = factory.CreateVideoProcessor();
}
public void Run(string audioFile, string videoFile)
{
_audioProcessor.ProcessAudio(audioFile);
_videoProcessor.ProcessVideo(videoFile);
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Using MP3 & MP4 formats:");
var mp3mp4Factory = new MP3MP4Factory();
var mp3mp4App = new MediaApplication(mp3mp4Factory);
mp3mp4App.Run("song.mp3", "video.mp4");
Console.WriteLine("\nUsing WAV & AVI formats:");
var wavaviFactory = new WAVAVIFactory();
var wavaviApp = new MediaApplication(wavaviFactory);
wavaviApp.Run("song.wav", "video.avi");
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IAudioProcessor
{
void ProcessAudio(string file);
}
public interface IVideoProcessor
{
void ProcessVideo(string file);
}
// Concrete Products for MP3 & MP4
public class MP3Processor : IAudioProcessor
{
public void ProcessAudio(string file)
{
Console.WriteLine($"Processing MP3 audio file: {file}");
}
}
public class MP4Processor : IVideoProcessor
{
public void ProcessVideo(string file)
{
Console.WriteLine($"Processing MP4 video file: {file}");
}
}
// Concrete Products for WAV & AVI
public class WAVProcessor : IAudioProcessor
{
public void ProcessAudio(string file)
{
Console.WriteLine($"Processing WAV audio file: {file}");
}
}
public class AVIProcessor : IVideoProcessor
{
public void ProcessVideo(string file)
{
Console.WriteLine($"Processing AVI video file: {file}");
}
}
// Abstract Factory
public interface IMediaFactory
{
IAudioProcessor CreateAudioProcessor();
IVideoProcessor CreateVideoProcessor();
}
// Concrete Factories
public class MP3MP4Factory : IMediaFactory
{
public IAudioProcessor CreateAudioProcessor() => new MP3Processor();
public IVideoProcessor CreateVideoProcessor() => new MP4Processor();
}
public class WAVAVIFactory : IMediaFactory
{
public IAudioProcessor CreateAudioProcessor() => new WAVProcessor();
public IVideoProcessor CreateVideoProcessor() => new AVIProcessor();
}
// Client Code
public class MediaApplication
{
private readonly IAudioProcessor _audioProcessor;
private readonly IVideoProcessor _videoProcessor;
public MediaApplication(IMediaFactory factory)
{
_audioProcessor = factory.CreateAudioProcessor();
_videoProcessor = factory.CreateVideoProcessor();
}
public void Run(string audioFile, string videoFile)
{
_audioProcessor.ProcessAudio(audioFile);
_videoProcessor.ProcessVideo(videoFile);
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Using MP3 & MP4 formats:");
var mp3mp4Factory = new MP3MP4Factory();
var mp3mp4App = new MediaApplication(mp3mp4Factory);
mp3mp4App.Run("song.mp3", "video.mp4");
Console.WriteLine("\nUsing WAV & AVI formats:");
var wavaviFactory = new WAVAVIFactory();
var wavaviApp = new MediaApplication(wavaviFactory);
wavaviApp.Run("song.wav", "video.avi");
Console.ReadKey();
}
}
}
In this real-time example, the Abstract Factory pattern ensures consistent processing tools for each combination of audio and video formats. This organized structure allows for easy scalability should you wish to add support for more formats in the future. When you run the above code, you will get the following output.

Real-Time Example of Abstract Factory Design Pattern in C#: Beverages
Consider a drink shop that offers both Coffee and Tea products. Each category (Coffee and Tea) has different types of products (like a cappuccino or green tea) and requires different ingredients (like milk, sugar, etc.). The Abstract Factory pattern can help organize the creation of these beverage products, ensuring all necessary ingredients are available. Let us see how we can implement the above example using the Abstract Factory Design Pattern in C#:
namespace AbstractFactoryDesignPattern
public interface IBeverage
public interface IIngredient
// Concrete Products for Coffee
public class Cappuccino : IBeverage
Console.WriteLine("Drinking Cappuccino!");
public class Milk : IIngredient
Console.WriteLine("Adding milk...");
// Concrete Products for Tea
public class GreenTea : IBeverage
Console.WriteLine("Drinking Green Tea!");
public class Sugar : IIngredient
Console.WriteLine("Adding sugar...");
public interface IBeverageFactory
IBeverage PrepareBeverage();
IIngredient AddIngredient();
public class CoffeeFactory : IBeverageFactory
public IBeverage PrepareBeverage() => new Cappuccino();
public IIngredient AddIngredient() => new Milk();
public class TeaFactory : IBeverageFactory
public IBeverage PrepareBeverage() => new GreenTea();
public IIngredient AddIngredient() => new Sugar();
public class BeverageMaker
private readonly IBeverage _beverage;
private readonly IIngredient _ingredient;
public BeverageMaker(IBeverageFactory factory)
_beverage = factory.PrepareBeverage();
_ingredient = factory.AddIngredient();
public void ServeBeverage()
// Testing the Abstract Factory Design Pattern
public static void Main()
Console.WriteLine("Ordering Coffee:");
var coffeeFactory = new CoffeeFactory();
var coffeeMaker = new BeverageMaker(coffeeFactory);
coffeeMaker.ServeBeverage();
Console.WriteLine("\nOrdering Tea:");
var teaFactory = new TeaFactory();
var teaMaker = new BeverageMaker(teaFactory);
teaMaker.ServeBeverage();
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IBeverage
{
void Drink();
}
public interface IIngredient
{
void Use();
}
// Concrete Products for Coffee
public class Cappuccino : IBeverage
{
public void Drink()
{
Console.WriteLine("Drinking Cappuccino!");
}
}
public class Milk : IIngredient
{
public void Use()
{
Console.WriteLine("Adding milk...");
}
}
// Concrete Products for Tea
public class GreenTea : IBeverage
{
public void Drink()
{
Console.WriteLine("Drinking Green Tea!");
}
}
public class Sugar : IIngredient
{
public void Use()
{
Console.WriteLine("Adding sugar...");
}
}
// Abstract Factory
public interface IBeverageFactory
{
IBeverage PrepareBeverage();
IIngredient AddIngredient();
}
// Concrete Factories
public class CoffeeFactory : IBeverageFactory
{
public IBeverage PrepareBeverage() => new Cappuccino();
public IIngredient AddIngredient() => new Milk();
}
public class TeaFactory : IBeverageFactory
{
public IBeverage PrepareBeverage() => new GreenTea();
public IIngredient AddIngredient() => new Sugar();
}
// Client Code
public class BeverageMaker
{
private readonly IBeverage _beverage;
private readonly IIngredient _ingredient;
public BeverageMaker(IBeverageFactory factory)
{
_beverage = factory.PrepareBeverage();
_ingredient = factory.AddIngredient();
}
public void ServeBeverage()
{
_ingredient.Use();
_beverage.Drink();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Ordering Coffee:");
var coffeeFactory = new CoffeeFactory();
var coffeeMaker = new BeverageMaker(coffeeFactory);
coffeeMaker.ServeBeverage();
Console.WriteLine("\nOrdering Tea:");
var teaFactory = new TeaFactory();
var teaMaker = new BeverageMaker(teaFactory);
teaMaker.ServeBeverage();
Console.ReadKey();
}
}
}
using System;
namespace AbstractFactoryDesignPattern
{
// Abstract Products
public interface IBeverage
{
void Drink();
}
public interface IIngredient
{
void Use();
}
// Concrete Products for Coffee
public class Cappuccino : IBeverage
{
public void Drink()
{
Console.WriteLine("Drinking Cappuccino!");
}
}
public class Milk : IIngredient
{
public void Use()
{
Console.WriteLine("Adding milk...");
}
}
// Concrete Products for Tea
public class GreenTea : IBeverage
{
public void Drink()
{
Console.WriteLine("Drinking Green Tea!");
}
}
public class Sugar : IIngredient
{
public void Use()
{
Console.WriteLine("Adding sugar...");
}
}
// Abstract Factory
public interface IBeverageFactory
{
IBeverage PrepareBeverage();
IIngredient AddIngredient();
}
// Concrete Factories
public class CoffeeFactory : IBeverageFactory
{
public IBeverage PrepareBeverage() => new Cappuccino();
public IIngredient AddIngredient() => new Milk();
}
public class TeaFactory : IBeverageFactory
{
public IBeverage PrepareBeverage() => new GreenTea();
public IIngredient AddIngredient() => new Sugar();
}
// Client Code
public class BeverageMaker
{
private readonly IBeverage _beverage;
private readonly IIngredient _ingredient;
public BeverageMaker(IBeverageFactory factory)
{
_beverage = factory.PrepareBeverage();
_ingredient = factory.AddIngredient();
}
public void ServeBeverage()
{
_ingredient.Use();
_beverage.Drink();
}
}
// Testing the Abstract Factory Design Pattern
public class Program
{
public static void Main()
{
Console.WriteLine("Ordering Coffee:");
var coffeeFactory = new CoffeeFactory();
var coffeeMaker = new BeverageMaker(coffeeFactory);
coffeeMaker.ServeBeverage();
Console.WriteLine("\nOrdering Tea:");
var teaFactory = new TeaFactory();
var teaMaker = new BeverageMaker(teaFactory);
teaMaker.ServeBeverage();
Console.ReadKey();
}
}
}
In this example, the Abstract Factory pattern helps segregate the creation of beverages and their ingredients based on their category (Coffee or Tea). This ensures consistency and allows for easy extension if the drink shop wants to introduce new beverage categories. When you run the above code, you will get the following output.

Advantages and Disadvantages of Abstract Factory Design Pattern in C#
The Abstract Factory design pattern is a popular creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. Here are the advantages and disadvantages of using the Abstract Factory design pattern:
Advantages of Abstract Factory Design Pattern in C#:
- Consistency: The pattern ensures that the created families of products are consistent and compatible. When you get a product from the factory, it’s guaranteed to work with the other products from the same family.
- Separation of Concerns: The creation logic of the products is isolated from the client code. This separation makes the system architecture cleaner and easier to maintain.
- Flexibility: By decoupling the client code from concrete product classes, you can change or extend the types of products the factory creates without altering client code.
- Scalability: It’s easy to introduce new product families or variants by simply extending the existing factories or adding new ones. This makes the system scalable in terms of product variations.
- Exchangeability: Client applications can switch between product families at runtime, allowing dynamic behavior based on configurations or environments.
Disadvantages of Abstract Factory Design Pattern in C#:
- Complexity: Introducing new classes and interfaces for factories and products can increase the system’s complexity, especially when many product families exist.
- Factory Proliferation: A new concrete factory must be created for each new family of products. This can lead to a proliferation of factory classes.
- Change Requires Subclassing: Introducing a new product across all families may require changes to the abstract factory interface and potentially all of its concrete subclasses, violating the open/closed principle.
- Initialization Overhead: The initialization process can be slightly heavier, especially when the system must decide between multiple product families during runtime.
- Indirection: While the pattern helps achieve decoupling, it also introduces another layer of abstraction, making the system harder to understand for newcomers.
In the next article, I will discuss the Builder Design Pattern in C# with Examples. Here, in this article, I try to explain Real-Time Examples of Abstract Factory Design Patterns in C#. I hope you enjoy this Abstract Factory Design Pattern Real-Time Examples using C# article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.